8199755: Update Graal
authordlong
Tue, 24 Apr 2018 09:04:57 -0700
changeset 49873 26ebfe8ce852
parent 49872 0798eab12791
child 49874 9e64b13a7fcb
8199755: Update Graal Reviewed-by: kvn
make/CompileJavaModules.gmk
make/CompileToolsHotspot.gmk
src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java
src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java
src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/package-info.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapLargeTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EquivalenceTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/PairTest.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordBoxFactory.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOpcode.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOperation.java
src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java
src/jdk.internal.vm.compiler/share/classes/module-info.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapImplTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapLargeTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicSetTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EquivalenceTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/PairTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMap.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMapImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Equivalence.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/MapCursor.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Pair.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicMap.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableMapCursor.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/package-info.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/SourceStackTraceBailoutException.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/PermanentBailoutException.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/RegisterAllocationConfig.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/doc-files/TraceInliningHelp.txt
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/FrequencyEncoder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReferenceGetLoopTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampMemoryAccessTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchRuleRegistry.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/CommunityCompilerConfiguration.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/CoreCompilerConfiguration.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyCompilerConfiguration.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CounterKeyImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugConfigImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/KeyRegistry.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Management.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKeyImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MetricKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimeSource.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/.checkstyle_checks.xml
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/CachedGraph.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSuitesProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStampMemoryAccessTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/aaa
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CommunityCompilerConfigurationFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CoreCompilerConfigurationFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EconomyCompilerConfigurationFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntimeProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/WeakClassLoaderSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/BeginLockScopeNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/EndLockScopeNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/StubForeignCallNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/AOTInliningPolicy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32CSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32Substitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HashCodeSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/LoadExceptionObjectSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/StringToBytesSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ThreadSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ExceptionHandlerStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/UnwindExceptionToCallerStub.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/KlassPointer.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MetaspacePointer.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MethodPointer.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/ComputeLoopFrequenciesClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/LocalLiveness.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayCompareToOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64AtomicMove.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SaveRegistersOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZapRegistersOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCSaveRegistersOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.test/src/org/graalvm/compiler/lir/test/alloc/trace/TraceGlobalMoveResolutionMappingTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/StandardOp.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/RegisterAllocationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/MoveResolver.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/PhiResolver.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/FixPointIntervalBuilder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/util/GenericValueMap.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentWhole.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EncodedGraph.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FieldLocationIdentity.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphSpeculationLog.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invokable.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/KillingBeginNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NamedLocationIdentity.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StartNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/HIRLoop.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/LocationSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/StringToBytesNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaReadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeAccessNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeCopyNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryLoadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryStoreNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryAccess.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryCheckpoint.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMap.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMapNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/MemoryProxy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/NestedBooleanOptionKeyTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/TestOptionKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/ModifiableOptionValues.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValuesAccess.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AbstractInlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AssumptionInlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/ExactInlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/InlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/CallsiteHolderExplorable.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/ComputeInliningRelevance.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/FixedNodeProbabilityCache.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/PostOrderNodeIterator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantNodeIterator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/SinglePassNodeIterator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/MemoryScheduleVerification.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadReplacementPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64StringLatin1Substitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64StringUTF16Substitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/NestedExceptionHandlerTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/D
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual.bench/.checkstyle.exclude
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsBlockState.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationBlockState.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualUtil.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/BarrieredAccess.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/ObjectAccess.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphElements.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphLocations.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/ObjectSizeEstimate.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/ComparableWord.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/LocationIdentity.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/Pointer.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/PointerBase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/SignedWord.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/UnsignedWord.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/WordBase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/WordFactory.java
--- a/make/CompileJavaModules.gmk	Tue Apr 24 08:13:30 2018 -0700
+++ b/make/CompileJavaModules.gmk	Tue Apr 24 09:04:57 2018 -0700
@@ -439,7 +439,7 @@
     #
 
 jdk.internal.vm.compiler_EXCLUDES += \
-    org.graalvm.collections.test \
+    jdk.internal.vm.compiler.collections.test \
     org.graalvm.compiler.core.match.processor \
     org.graalvm.compiler.nodeinfo.processor \
     org.graalvm.compiler.options.processor \
--- a/make/CompileToolsHotspot.gmk	Tue Apr 24 08:13:30 2018 -0700
+++ b/make/CompileToolsHotspot.gmk	Tue Apr 24 09:04:57 2018 -0700
@@ -47,8 +47,8 @@
   $(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_MATCH_PROCESSOR, \
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
-          $(SRC_DIR)/org.graalvm.word/src \
-          $(SRC_DIR)/org.graalvm.collections/src \
+          $(SRC_DIR)/jdk.internal.vm.compiler.word/src \
+          $(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
           $(SRC_DIR)/org.graalvm.compiler.core/src \
           $(SRC_DIR)/org.graalvm.compiler.core.common/src \
           $(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
@@ -102,7 +102,7 @@
   $(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
-          $(SRC_DIR)/org.graalvm.collections/src \
+          $(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
           $(SRC_DIR)/org.graalvm.compiler.options/src \
           $(SRC_DIR)/org.graalvm.compiler.options.processor/src \
           $(SRC_DIR)/org.graalvm.util/src \
@@ -118,8 +118,8 @@
   $(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_REPLACEMENTS_VERIFIER, \
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
-          $(SRC_DIR)/org.graalvm.word/src \
-          $(SRC_DIR)/org.graalvm.collections/src \
+          $(SRC_DIR)/jdk.internal.vm.compiler.word/src \
+          $(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
           $(SRC_DIR)/org.graalvm.compiler.bytecode/src \
           $(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
           $(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,11 +30,11 @@
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.GraalCompilerOptions;
 import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.Management;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.debug.DebugContext.Activation;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
@@ -52,8 +52,6 @@
 
     private static final AtomicInteger ids = new AtomicInteger();
 
-    private static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
-
     private final Main main;
 
     private OptionValues graalOptions;
@@ -99,7 +97,7 @@
 
         final long threadId = Thread.currentThread().getId();
 
-        final boolean printCompilation = GraalCompilerOptions.PrintCompilation.getValue(graalOptions) && !TTY.isSuppressed();
+        final boolean printCompilation = GraalCompilerOptions.PrintCompilation.getValue(graalOptions) && !TTY.isSuppressed() && GraalServices.isThreadAllocatedMemorySupported();
         if (printCompilation) {
             TTY.println(getMethodDescription() + "...");
         }
@@ -108,7 +106,7 @@
         final long allocatedBytesBefore;
         if (printCompilation) {
             start = System.currentTimeMillis();
-            allocatedBytesBefore = printCompilation ? threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
+            allocatedBytesBefore = GraalServices.getThreadAllocatedBytes(threadId);
         } else {
             start = 0L;
             allocatedBytesBefore = 0L;
@@ -125,7 +123,7 @@
         if (printCompilation) {
             final long stop = System.currentTimeMillis();
             final int targetCodeSize = compResult != null ? compResult.getTargetCodeSize() : -1;
-            final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId);
+            final long allocatedBytesAfter = GraalServices.getThreadAllocatedBytes(threadId);
             final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
 
             TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes));
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java	Tue Apr 24 09:04:57 2018 -0700
@@ -45,7 +45,7 @@
 import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
 import org.graalvm.compiler.hotspot.word.MetaspacePointer;
 import org.graalvm.compiler.replacements.Snippets;
-import org.graalvm.word.WordBase;
+import jdk.internal.vm.compiler.word.WordBase;
 
 final class GraalFilters {
     private List<ResolvedJavaType> specialClasses;
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Tue Apr 24 09:04:57 2018 -0700
@@ -141,7 +141,7 @@
                 graalOptions = new OptionValues(graalOptions, TieredAOT, options.tiered);
             }
             graalOptions = new OptionValues(graalOptions, GeneratePIC, true, ImmutableCode, true);
-            GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler(JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
+            GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler("JAOTC", JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
             HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
             HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
             MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,154 @@
  */
 package org.graalvm.compiler.hotspot.management;
 
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+
 /**
- * Placeholder until next Graal update.
+ * Dynamically registers an MBean with the {@link ManagementFactory#getPlatformMBeanServer()}.
+ *
+ * Polling for an active platform MBean server is done by calling
+ * {@link MBeanServerFactory#findMBeanServer(String)} with an argument value of {@code null}. Once
+ * this returns an non-empty list, {@link ManagementFactory#getPlatformMBeanServer()} can be called
+ * to obtain a reference to the platform MBean server instance.
  */
-public final class HotSpotGraalManagement  {
+@ServiceProvider(HotSpotGraalManagementRegistration.class)
+public final class HotSpotGraalManagement implements HotSpotGraalManagementRegistration {
+
+    private HotSpotGraalRuntimeMBean bean;
+    private volatile boolean needsRegistration = true;
+    HotSpotGraalManagement nextDeferred;
+
+    @Override
+    public void initialize(HotSpotGraalRuntime runtime) {
+        if (bean == null) {
+            if (runtime.getManagement() != this) {
+                throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName());
+            }
+            try {
+                String name = runtime.getName().replace(':', '_');
+                ObjectName objectName = new ObjectName("org.graalvm.compiler.hotspot:type=" + name);
+                bean = new HotSpotGraalRuntimeMBean(objectName, runtime);
+                registration.add(this);
+            } catch (MalformedObjectNameException err) {
+                err.printStackTrace(TTY.out);
+            }
+        } else if (bean.getRuntime() != runtime) {
+            throw new IllegalArgumentException("Cannot change the runtime a management interface is associated with");
+        }
+    }
+
+    static final class RegistrationThread extends Thread {
+
+        private MBeanServer platformMBeanServer;
+        private HotSpotGraalManagement deferred;
+
+        RegistrationThread() {
+            super("HotSpotGraalManagement Bean Registration");
+            this.setPriority(Thread.MIN_PRIORITY);
+            this.setDaemon(true);
+            this.start();
+        }
+
+        /**
+         * Poll for active MBean server every 2 seconds.
+         */
+        private static final int POLL_INTERVAL_MS = 2000;
+
+        /**
+         * Adds a {@link HotSpotGraalManagement} to register with an active MBean server when one
+         * becomes available.
+         */
+        synchronized void add(HotSpotGraalManagement e) {
+            if (deferred != null) {
+                e.nextDeferred = deferred;
+            }
+            deferred = e;
+
+            // Notify the registration thread that there is now
+            // a deferred registration to process
+            notify();
+        }
+
+        /**
+         * Processes and clears any deferred registrations.
+         */
+        private void process() {
+            for (HotSpotGraalManagement m = deferred; m != null; m = m.nextDeferred) {
+                HotSpotGraalRuntimeMBean bean = m.bean;
+                if (m.needsRegistration && bean != null) {
+                    try {
+                        platformMBeanServer.registerMBean(bean, bean.getObjectName());
+                    } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
+                        e.printStackTrace(TTY.out);
+                        // Registration failed - don't try again
+                        m.bean = null;
+                    }
+                    m.needsRegistration = false;
+                }
+            }
+            deferred = null;
+        }
+
+        @Override
+        public void run() {
+            while (true) {
+                try {
+                    synchronized (this) {
+                        // Wait until there are deferred registrations to process
+                        while (deferred == null) {
+                            wait();
+                        }
+                    }
+                    poll();
+                    Thread.sleep(POLL_INTERVAL_MS);
+                } catch (InterruptedException e) {
+                    // Be verbose about unexpected interruption and then continue
+                    e.printStackTrace(TTY.out);
+                }
+            }
+        }
+
+        /**
+         * Checks for active MBean server and if available, processes deferred registrations.
+         */
+        synchronized void poll() {
+            if (platformMBeanServer == null) {
+                ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
+                if (!servers.isEmpty()) {
+                    platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
+                    process();
+                }
+            } else {
+                process();
+            }
+        }
+    }
+
+    private static final RegistrationThread registration = new RegistrationThread();
+
+    @Override
+    public ObjectName poll(boolean sync) {
+        if (sync) {
+            registration.poll();
+        }
+        if (bean == null || needsRegistration) {
+            // initialize() has not been called, it failed or registration failed
+            return null;
+        }
+        return bean.getObjectName();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.management;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import org.graalvm.compiler.core.common.SuppressFBWarnings;
+import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
+import org.graalvm.compiler.options.OptionDescriptor;
+import org.graalvm.compiler.options.OptionDescriptors;
+import org.graalvm.compiler.options.OptionsParser;
+
+/**
+ * MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
+ */
+final class HotSpotGraalRuntimeMBean implements DynamicMBean {
+
+    /**
+     * The runtime instance to which this bean provides a management connection.
+     */
+    private final HotSpotGraalRuntime runtime;
+
+    /**
+     * The object name under which the bean is registered.
+     */
+    private final ObjectName objectName;
+
+    HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
+        this.objectName = objectName;
+        this.runtime = runtime;
+    }
+
+    ObjectName getObjectName() {
+        return objectName;
+    }
+
+    HotSpotGraalRuntime getRuntime() {
+        return runtime;
+    }
+
+    private static final boolean DEBUG = Boolean.getBoolean(HotSpotGraalRuntimeMBean.class.getSimpleName() + ".debug");
+
+    @Override
+    public Object getAttribute(String name) throws AttributeNotFoundException {
+        String[] result = runtime.getOptionValues(name);
+        String value = result[0];
+        if (value == null) {
+            throw new AttributeNotFoundException(name);
+        }
+        if (DEBUG) {
+            System.out.printf("getAttribute: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName());
+        }
+        return result[0];
+    }
+
+    @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want")
+    @Override
+    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException {
+        String name = attribute.getName();
+        Object value = attribute.getValue();
+        String svalue = String.valueOf(value);
+        if (DEBUG) {
+            System.out.printf("setAttribute: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName());
+        }
+        String[] result = runtime.setOptionValues(new String[]{name}, new String[]{svalue});
+        if (result[0] != name) {
+            if (result[0] == null) {
+                throw new AttributeNotFoundException(name);
+            }
+            throw new InvalidAttributeValueException(result[0]);
+        }
+    }
+
+    @Override
+    public AttributeList getAttributes(String[] names) {
+        String[] values = runtime.getOptionValues(names);
+        AttributeList list = new AttributeList();
+        for (int i = 0; i < names.length; i++) {
+            String value = values[i];
+            String name = names[i];
+            if (value == null) {
+                TTY.printf("No such option named %s%n", name);
+            } else {
+                if (DEBUG) {
+                    System.out.printf("getAttributes: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName());
+                }
+                list.add(new Attribute(name, value));
+            }
+        }
+        return list;
+    }
+
+    @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want")
+    @Override
+    public AttributeList setAttributes(AttributeList attributes) {
+        String[] names = new String[attributes.size()];
+        String[] values = new String[attributes.size()];
+
+        int i = 0;
+        for (Attribute attr : attributes.asList()) {
+            String name = attr.getName();
+            names[i] = name;
+            Object value = attr.getValue();
+            String svalue = String.valueOf(value);
+            values[i] = svalue;
+            if (DEBUG) {
+                System.out.printf("setAttributes: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName());
+            }
+            i++;
+        }
+        String[] result = runtime.setOptionValues(names, values);
+        AttributeList setOk = new AttributeList();
+        i = 0;
+        for (Attribute attr : attributes.asList()) {
+            if (names[i] == result[i]) {
+                setOk.add(attr);
+            } else if (result[i] == null) {
+                TTY.printf("Error setting %s to %s: unknown option%n", attr.getName(), attr.getValue());
+            } else {
+                TTY.printf("Error setting %s to %s: %s%n", attr.getName(), attr.getValue(), result[i]);
+            }
+            i++;
+        }
+        return setOk;
+    }
+
+    @Override
+    public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
+        try {
+            if (DEBUG) {
+                System.out.printf("invoke: %s%s%n", actionName, Arrays.asList(params));
+            }
+            Object retvalue = runtime.invokeManagementAction(actionName, params);
+            if (DEBUG) {
+                System.out.printf("invoke: %s%s = %s%n", actionName, Arrays.asList(params), retvalue);
+            }
+            return retvalue;
+        } catch (Exception ex) {
+            throw new ReflectionException(ex);
+        }
+    }
+
+    @Override
+    public MBeanInfo getMBeanInfo() {
+        List<MBeanAttributeInfo> attrs = new ArrayList<>();
+        for (OptionDescriptor option : getOptionDescriptors().getValues()) {
+            Class<?> optionValueType = option.getOptionValueType();
+            if (Enum.class.isAssignableFrom(optionValueType)) {
+                // Enum values are passed through
+                // the management interface as Strings.
+                optionValueType = String.class;
+            }
+            attrs.add(new MBeanAttributeInfo(option.getName(), optionValueType.getName(), option.getHelp(), true, true, false));
+        }
+        attrs.sort(new Comparator<MBeanAttributeInfo>() {
+            @Override
+            public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2) {
+                return o1.getName().compareTo(o2.getName());
+            }
+        });
+        MBeanOperationInfo[] ops = {
+                        new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+                                        new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+                                        new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+                        }, "void", MBeanOperationInfo.ACTION),
+                        new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+                                        new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+                                        new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+                                        new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
+                        }, "void", MBeanOperationInfo.ACTION),
+                        new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+                                        new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+                                        new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+                                        new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
+                                        new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
+                                        new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
+                        }, "void", MBeanOperationInfo.ACTION)
+        };
+
+        return new MBeanInfo(
+                        HotSpotGraalRuntimeMBean.class.getName(),
+                        "Graal",
+                        attrs.toArray(new MBeanAttributeInfo[attrs.size()]),
+                        null, ops, null);
+    }
+
+    private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() {
+        EconomicMap<String, OptionDescriptor> result = EconomicMap.create();
+        for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
+            for (OptionDescriptor option : set) {
+                result.put(option.getName(), option);
+            }
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.management;
+
+import static java.lang.Thread.currentThread;
+
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+import org.graalvm.compiler.serviceprovider.GraalServices.JMXService;
+
+import com.sun.management.ThreadMXBean;
+
+/**
+ * Implementation of {@link JMXService} for JDK 11 and later.
+ */
+@ServiceProvider(JMXService.class)
+public class JMXServiceProvider extends JMXService {
+    private final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
+
+    @Override
+    protected long getThreadAllocatedBytes(long id) {
+        return threadMXBean.getThreadAllocatedBytes(id);
+    }
+
+    @Override
+    protected long getCurrentThreadCpuTime() {
+        long[] times = threadMXBean.getThreadCpuTime(new long[]{currentThread().getId()});
+        return times[0];
+    }
+
+    @Override
+    protected boolean isThreadAllocatedMemorySupported() {
+        return threadMXBean.isThreadAllocatedMemorySupported();
+    }
+
+    @Override
+    protected boolean isCurrentThreadCpuTimeSupported() {
+        return threadMXBean.isThreadCpuTimeSupported();
+    }
+
+    @Override
+    protected List<String> getInputArguments() {
+        return ManagementFactory.getRuntimeMXBean().getInputArguments();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/package-info.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK 11 and later versioned overlay for the {@code jdk.internal.vm.compiler.management} module.
+ * This cannot be used in JDK 10 where {@code jdk.internal.vm.compiler.management} is a
+ * non-upgradeable module.
+ */
+package org.graalvm.compiler.hotspot.management;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicSet;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EconomicMapImplTest {
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testRemoveNull() {
+        EconomicMap<Integer, Integer> map = EconomicMap.create(10);
+        map.removeKey(null);
+    }
+
+    @Test
+    public void testInitFromHashSet() {
+        UnmodifiableEconomicSet<Integer> set = new UnmodifiableEconomicSet<Integer>() {
+
+            @Override
+            public boolean contains(Integer element) {
+                return element == 0;
+            }
+
+            @Override
+            public int size() {
+                return 1;
+            }
+
+            @Override
+            public boolean isEmpty() {
+                return false;
+            }
+
+            @Override
+            public Iterator<Integer> iterator() {
+                return new Iterator<Integer>() {
+
+                    private boolean visited = false;
+
+                    @Override
+                    public boolean hasNext() {
+                        return !visited;
+                    }
+
+                    @Override
+                    public Integer next() {
+                        if (visited) {
+                            return null;
+                        } else {
+                            visited = true;
+                            return 1;
+                        }
+                    }
+                };
+            }
+        };
+
+        EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.DEFAULT, set);
+        Assert.assertEquals(newSet.size(), 1);
+    }
+
+    @Test
+    public void testCopyHash() {
+        EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
+        set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+        EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.IDENTITY, set);
+        Assert.assertEquals(newSet.size(), 10);
+        newSet.remove(8);
+        newSet.remove(9);
+        Assert.assertEquals(newSet.size(), 8);
+    }
+
+    @Test
+    public void testNewEquivalence() {
+        EconomicSet<Integer> set = EconomicSet.create(new Equivalence() {
+            @Override
+            public boolean equals(Object a, Object b) {
+                return false;
+            }
+
+            @Override
+            public int hashCode(Object o) {
+                return 0;
+            }
+        });
+        set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+        Assert.assertTrue(set.add(new Integer(0)));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testMapPutNull() {
+        EconomicMap<Integer, Integer> map = EconomicMap.create();
+        map.put(null, null);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapLargeTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Objects;
+import java.util.Random;
+
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class EconomicMapLargeTest {
+
+    @Parameter(value = 0) public EconomicMap<Object, Object> testMap;
+    @Parameter(value = 1) public EconomicMap<Object, Object> referenceMap;
+    @Parameter(value = 2) public String name;
+
+    @Parameters(name = "{2}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.create(Equivalence.DEFAULT), "EconomicMap"},
+                        new Object[]{EconomicMap.create(Equivalence.IDENTITY), EconomicMap.create(Equivalence.IDENTITY), "EconomicMap(IDENTITY)"},
+                        new Object[]{EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE), EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE),
+                                        "EconomicMap(IDENTITY_WITH_SYSTEM_HASHCODE)"},
+                        new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.wrapMap(new LinkedHashMap<>()), "EconomicMap<->wrapMap"},
+                        new Object[]{EconomicMap.wrapMap(new LinkedHashMap<>()), EconomicMap.wrapMap(new LinkedHashMap<>()), "wrapMap"});
+    }
+
+    private static int[] createRandomRange(Random random, int count) {
+        int[] result = new int[count];
+        for (int i = 0; i < count; ++i) {
+            int range = random.nextInt(14);
+            if (range == 0 || range > 10) {
+                range = Integer.MAX_VALUE;
+            } else if (range == 10) {
+                range = 100;
+            }
+            result[i] = range;
+        }
+        return result;
+    }
+
+    private static final class BadHashClass {
+        private int value;
+
+        BadHashClass(int randomInt) {
+            this.value = randomInt;
+        }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof BadHashClass) {
+                BadHashClass badHashClass = (BadHashClass) other;
+                return badHashClass.value == value;
+            }
+            return false;
+        }
+    }
+
+    interface MapAction {
+        Object perform(EconomicMap<Object, Object> map, int randomInt);
+    }
+
+    static final Object EXISTING_VALUE = new Object();
+
+    static final MapAction[] INCREASE_ACTIONS = new MapAction[]{
+                    (map, randomInt) -> map.put(randomInt, "value"),
+                    (map, randomInt) -> map.get(randomInt)
+    };
+
+    static final MapAction[] ACTIONS = new MapAction[]{
+                    (map, randomInt) -> map.removeKey(randomInt),
+                    (map, randomInt) -> map.put(randomInt, "value"),
+                    (map, randomInt) -> map.put(randomInt, null),
+                    (map, randomInt) -> map.put(EXISTING_VALUE, randomInt),
+                    (map, randomInt) -> {
+                        if (randomInt == 0) {
+                            map.clear();
+                        }
+                        return map.isEmpty();
+                    },
+                    (map, randomInt) -> map.containsKey(randomInt),
+                    (map, randomInt) -> map.get(randomInt),
+                    (map, randomInt) -> map.put(new BadHashClass(randomInt), "unique"),
+                    (map, randomInt) -> {
+                        if (randomInt == 0) {
+                            map.replaceAll((key, value) -> Objects.toString(value) + "!");
+                        }
+                        return map.isEmpty();
+                    }
+
+    };
+
+    @Test
+    public void testVeryLarge() {
+        testMap.clear();
+        referenceMap.clear();
+
+        Random random = new Random(0);
+        for (int i = 0; i < 200000; ++i) {
+            for (int j = 0; j < INCREASE_ACTIONS.length; ++j) {
+                int nextInt = random.nextInt(10000000);
+                MapAction action = INCREASE_ACTIONS[j];
+                Object result = action.perform(testMap, nextInt);
+                Object referenceResult = action.perform(referenceMap, nextInt);
+                Assert.assertEquals(result, referenceResult);
+            }
+        }
+    }
+
+    /**
+     * Tests a sequence of random operations on the map.
+     */
+    @Test
+    public void testAddRemove() {
+        testMap.clear();
+        referenceMap.clear();
+
+        for (int seed = 0; seed < 10; ++seed) {
+            Random random = new Random(seed);
+            int[] ranges = createRandomRange(random, ACTIONS.length);
+            int value = random.nextInt(10000);
+            for (int i = 0; i < value; ++i) {
+                for (int j = 0; j < ACTIONS.length; ++j) {
+                    if (random.nextInt(ranges[j]) == 0) {
+                        int nextInt = random.nextInt(100);
+                        MapAction action = ACTIONS[j];
+                        Object result = action.perform(testMap, nextInt);
+                        Object referenceResult = action.perform(referenceMap, nextInt);
+                        Assert.assertEquals(result, referenceResult);
+                        if (j % 100 == 0) {
+                            checkEquality(testMap, referenceMap);
+                        }
+                    }
+                }
+
+                if (random.nextInt(20) == 0) {
+                    removeElement(random.nextInt(100), testMap, referenceMap);
+                }
+            }
+        }
+    }
+
+    private static void removeElement(int index, EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
+        Assert.assertEquals(referenceMap.size(), map.size());
+        MapCursor<?, ?> cursor = map.getEntries();
+        MapCursor<?, ?> referenceCursor = referenceMap.getEntries();
+        int z = 0;
+        while (cursor.advance()) {
+            Assert.assertTrue(referenceCursor.advance());
+            Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
+            Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
+            if (index == z) {
+                cursor.remove();
+                referenceCursor.remove();
+            }
+            ++z;
+        }
+
+        Assert.assertFalse(referenceCursor.advance());
+    }
+
+    private static void checkEquality(EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
+        Assert.assertEquals(referenceMap.size(), map.size());
+
+        // Check entries.
+        UnmodifiableMapCursor<?, ?> cursor = map.getEntries();
+        UnmodifiableMapCursor<?, ?> referenceCursor = referenceMap.getEntries();
+        while (cursor.advance()) {
+            Assert.assertTrue(referenceCursor.advance());
+            Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
+            Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
+        }
+
+        // Check keys.
+        Iterator<?> iterator = map.getKeys().iterator();
+        Iterator<?> referenceIterator = referenceMap.getKeys().iterator();
+        while (iterator.hasNext()) {
+            Assert.assertTrue(referenceIterator.hasNext());
+            Assert.assertEquals(iterator.next(), referenceIterator.next());
+        }
+
+        // Check values.
+        iterator = map.getValues().iterator();
+        referenceIterator = referenceMap.getValues().iterator();
+        while (iterator.hasNext()) {
+            Assert.assertTrue(referenceIterator.hasNext());
+            Assert.assertEquals(iterator.next(), referenceIterator.next());
+        }
+        Assert.assertFalse(referenceIterator.hasNext());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import java.util.LinkedHashMap;
+
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EconomicMapTest {
+
+    @Test
+    public void testMapGetDefault() {
+        EconomicMap<Integer, Integer> map = EconomicMap.create();
+        map.put(0, 1);
+        Assert.assertEquals(map.get(0, 2), Integer.valueOf(1));
+        Assert.assertEquals(map.get(1, 2), Integer.valueOf(2));
+    }
+
+    @Test
+    public void testMapPutAll() {
+        EconomicMap<Integer, Integer> map = EconomicMap.create();
+        EconomicMap<Integer, Integer> newMap = EconomicMap.wrapMap(new LinkedHashMap<>());
+        newMap.put(1, 1);
+        newMap.put(2, 4);
+        map.putAll(newMap);
+        Assert.assertEquals(map.size(), 2);
+
+        UnmodifiableEconomicMap<Integer, Integer> unmodifiableEconomicMap = EconomicMap.create(newMap);
+
+        map.removeKey(1);
+        map.put(2, 2);
+        map.put(3, 9);
+
+        map.putAll(unmodifiableEconomicMap);
+        Assert.assertEquals(map.size(), 3);
+        Assert.assertEquals(map.get(2), Integer.valueOf(4));
+    }
+
+    @Test
+    public void testToString() {
+        EconomicMap<Integer, Integer> map = EconomicMap.create();
+        map.put(0, 0);
+        map.put(1, 1);
+        Assert.assertEquals(map.toString(), "map(size=2, {(0,0),(1,1)})");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EconomicSetTest {
+
+    @Test
+    public void testUtilities() {
+        EconomicSet<Integer> set = EconomicSet.create(0);
+        set.add(0);
+        Assert.assertTrue(set.add(1));
+        Assert.assertEquals(set.size(), 2);
+        Assert.assertFalse(set.add(1));
+        Assert.assertEquals(set.size(), 2);
+        set.remove(1);
+        Assert.assertEquals(set.size(), 1);
+        set.remove(2);
+        Assert.assertEquals(set.size(), 1);
+        Assert.assertTrue(set.add(1));
+        set.clear();
+        Assert.assertEquals(set.size(), 0);
+    }
+
+    @Test
+    public void testAddAll() {
+        EconomicSet<Integer> set = EconomicSet.create();
+        set.addAll(Arrays.asList(0, 1, 0));
+        Assert.assertEquals(set.size(), 2);
+
+        EconomicSet<Integer> newSet = EconomicSet.create();
+        newSet.addAll(Arrays.asList(1, 2));
+        Assert.assertEquals(newSet.size(), 2);
+        newSet.addAll(set);
+        Assert.assertEquals(newSet.size(), 3);
+    }
+
+    @Test
+    public void testRemoveAll() {
+        EconomicSet<Integer> set = EconomicSet.create();
+        set.addAll(Arrays.asList(0, 1));
+
+        set.removeAll(Arrays.asList(1, 2));
+        Assert.assertEquals(set.size(), 1);
+
+        set.removeAll(EconomicSet.create(set));
+        Assert.assertEquals(set.size(), 0);
+    }
+
+    @Test
+    public void testRetainAll() {
+        EconomicSet<Integer> set = EconomicSet.create();
+        set.addAll(Arrays.asList(0, 1, 2));
+
+        EconomicSet<Integer> newSet = EconomicSet.create();
+        newSet.addAll(Arrays.asList(2, 3));
+
+        set.retainAll(newSet);
+        Assert.assertEquals(set.size(), 1);
+    }
+
+    @Test
+    public void testToArray() {
+        EconomicSet<Integer> set = EconomicSet.create();
+        set.addAll(Arrays.asList(0, 1));
+        Assert.assertArrayEquals(set.toArray(new Integer[2]), new Integer[]{0, 1});
+    }
+
+    @Test
+    public void testToString() {
+        EconomicSet<Integer> set = EconomicSet.create();
+        set.addAll(Arrays.asList(0, 1));
+        Assert.assertEquals(set.toString(), "set(size=2, {0,1})");
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testToUnalignedArray() {
+        Assert.assertArrayEquals(EconomicSet.create().toArray(new Integer[2]), new Integer[0]);
+    }
+
+    @Test
+    public void testSetRemoval() {
+        ArrayList<Integer> initialList = new ArrayList<>();
+        ArrayList<Integer> removalList = new ArrayList<>();
+        ArrayList<Integer> finalList = new ArrayList<>();
+        EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
+        set.add(1);
+        set.add(2);
+        set.add(3);
+        set.add(4);
+        set.add(5);
+        set.add(6);
+        set.add(7);
+        set.add(8);
+        set.add(9);
+        Iterator<Integer> i1 = set.iterator();
+        while (i1.hasNext()) {
+            initialList.add(i1.next());
+        }
+        int size = 0;
+        Iterator<Integer> i2 = set.iterator();
+        while (i2.hasNext()) {
+            Integer elem = i2.next();
+            if (size++ < 8) {
+                i2.remove();
+            }
+            removalList.add(elem);
+        }
+        Iterator<Integer> i3 = set.iterator();
+        while (i3.hasNext()) {
+            finalList.add(i3.next());
+        }
+        Assert.assertEquals(initialList, removalList);
+        Assert.assertEquals(1, finalList.size());
+        Assert.assertEquals(new Integer(9), finalList.get(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EquivalenceTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import jdk.internal.vm.compiler.collections.Equivalence;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EquivalenceTest {
+
+    private static final String TEST_STRING = "Graal";
+    private static final String TEST_STRING2 = "Graal2";
+
+    @Test
+    public void testDEFAULT() {
+        Assert.assertTrue(Equivalence.DEFAULT.equals(TEST_STRING, new String(TEST_STRING)));
+        Assert.assertEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(new String(TEST_STRING)));
+        Assert.assertFalse(Equivalence.DEFAULT.equals(TEST_STRING, TEST_STRING2));
+        Assert.assertNotEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(TEST_STRING2));
+    }
+
+    @Test
+    public void testIDENTITY() {
+        Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, new String(TEST_STRING)));
+        Assert.assertEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(new String(TEST_STRING)));
+        Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, TEST_STRING2));
+        Assert.assertNotEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(TEST_STRING2));
+    }
+
+    @Test
+    public void testIDENTITYWITHSYSTEMHASHCODE() {
+        Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, new String(TEST_STRING)));
+        Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(new String(TEST_STRING)));
+        Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, TEST_STRING2));
+        Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/PairTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections.test;
+
+import jdk.internal.vm.compiler.collections.Pair;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PairTest {
+
+    @Test
+    public void testCreate() {
+        Assert.assertEquals(Pair.create(null, null), Pair.empty());
+        Assert.assertNotEquals(Pair.create(null, null), null);
+        Assert.assertEquals(Pair.createLeft(null), Pair.empty());
+        Assert.assertEquals(Pair.createRight(null), Pair.empty());
+        Assert.assertEquals(Pair.create(1, null), Pair.createLeft(1));
+        Assert.assertEquals(Pair.create(null, 1), Pair.createRight(1));
+    }
+
+    @Test
+    public void testUtilities() {
+        Pair<Integer, Integer> pair = Pair.create(1, null);
+        Assert.assertEquals(pair.getLeft(), Integer.valueOf(1));
+        Assert.assertEquals(pair.getRight(), null);
+        Assert.assertEquals(pair.toString(), "(1, null)");
+        Assert.assertEquals(pair.hashCode(), Pair.createLeft(1).hashCode());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+/**
+ * Memory efficient map data structure.
+ *
+ * @since 1.0
+ */
+public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
+
+    /**
+     * Associates {@code value} with {@code key} in this map. If the map previously contained a
+     * mapping for {@code key}, the old value is replaced by {@code value}.
+     *
+     * @return the previous value associated with {@code key}, or {@code null} if there was no
+     *         mapping for {@code key}.
+     * @since 1.0
+     */
+    V put(K key, V value);
+
+    /**
+     * Copies all of the mappings from {@code other} to this map.
+     *
+     * @since 1.0
+     */
+    default void putAll(EconomicMap<K, V> other) {
+        MapCursor<K, V> e = other.getEntries();
+        while (e.advance()) {
+            put(e.getKey(), e.getValue());
+        }
+    }
+
+    /**
+     * Copies all of the mappings from {@code other} to this map.
+     *
+     * @since 1.0
+     */
+    default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
+        UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
+        while (entry.advance()) {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Removes all of the mappings from this map. The map will be empty after this call returns.
+     *
+     * @since 1.0
+     */
+    void clear();
+
+    /**
+     * Removes the mapping for {@code key} from this map if it is present. The map will not contain
+     * a mapping for {@code key} once the call returns.
+     *
+     * @return the previous value associated with {@code key}, or {@code null} if there was no
+     *         mapping for {@code key}.
+     * @since 1.0
+     */
+    V removeKey(K key);
+
+    /**
+     * Returns a {@link MapCursor} view of the mappings contained in this map.
+     *
+     * @since 1.0
+     */
+    @Override
+    MapCursor<K, V> getEntries();
+
+    /**
+     * Replaces each entry's value with the result of invoking {@code function} on that entry until
+     * all entries have been processed or the function throws an exception. Exceptions thrown by the
+     * function are relayed to the caller.
+     *
+     * @since 1.0
+     */
+    void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set with the default
+     * {@link Equivalence#DEFAULT} comparison strategy for keys.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create() {
+        return EconomicMap.create(Equivalence.DEFAULT);
+    }
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set with the default
+     * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
+     * capacity.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create(int initialCapacity) {
+        return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
+    }
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set with the given comparison
+     * strategy for keys.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
+        return EconomicMapImpl.create(strategy, false);
+    }
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set with the default
+     * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
+     * specified existing map.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
+        return EconomicMap.create(Equivalence.DEFAULT, m);
+    }
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set and copies all elements from
+     * the specified existing map.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
+        return EconomicMapImpl.create(strategy, m, false);
+    }
+
+    /**
+     * Creates a new map that guarantees insertion order on the key set and initializes with a
+     * specified capacity.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
+        return EconomicMapImpl.create(strategy, initialCapacity, false);
+    }
+
+    /**
+     * Wraps an existing {@link Map} as an {@link EconomicMap}.
+     *
+     * @since 1.0
+     */
+    static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
+        return new EconomicMap<K, V>() {
+
+            @Override
+            public V get(K key) {
+                V result = map.get(key);
+                return result;
+            }
+
+            @Override
+            public V put(K key, V value) {
+                V result = map.put(key, value);
+                return result;
+            }
+
+            @Override
+            public int size() {
+                int result = map.size();
+                return result;
+            }
+
+            @Override
+            public boolean containsKey(K key) {
+                return map.containsKey(key);
+            }
+
+            @Override
+            public void clear() {
+                map.clear();
+            }
+
+            @Override
+            public V removeKey(K key) {
+                V result = map.remove(key);
+                return result;
+            }
+
+            @Override
+            public Iterable<V> getValues() {
+                return map.values();
+            }
+
+            @Override
+            public Iterable<K> getKeys() {
+                return map.keySet();
+            }
+
+            @Override
+            public boolean isEmpty() {
+                return map.isEmpty();
+            }
+
+            @Override
+            public MapCursor<K, V> getEntries() {
+                Iterator<java.util.Map.Entry<K, V>> iterator = map.entrySet().iterator();
+                return new MapCursor<K, V>() {
+
+                    private Map.Entry<K, V> current;
+
+                    @Override
+                    public boolean advance() {
+                        boolean result = iterator.hasNext();
+                        if (result) {
+                            current = iterator.next();
+                        }
+
+                        return result;
+                    }
+
+                    @Override
+                    public K getKey() {
+                        return current.getKey();
+                    }
+
+                    @Override
+                    public V getValue() {
+                        return current.getValue();
+                    }
+
+                    @Override
+                    public void remove() {
+                        iterator.remove();
+                    }
+                };
+            }
+
+            @Override
+            public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+                map.replaceAll(function);
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.function.BiFunction;
+
+/**
+ * Implementation of a map with a memory-efficient structure that always preserves insertion order
+ * when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal
+ * {@link #INITIAL_CAPACITY} or smaller 256.
+ *
+ * The key/value pairs are kept in an expanding flat object array with keys at even indices and
+ * values at odd indices. If the map has smaller or equal to {@link #HASH_THRESHOLD} entries, there
+ * is no additional hash data structure and comparisons are done via linear checking of the
+ * key/value pairs. For the case where the equality check is particularly cheap (e.g., just an
+ * object identity comparison), this limit below which the map is without an actual hash table is
+ * higher and configured at {@link #HASH_THRESHOLD_IDENTITY_COMPARE}.
+ *
+ * When the hash table needs to be constructed, the field {@link #hashArray} becomes a new hash
+ * array where an entry of 0 means no hit and otherwise denotes the entry number in the
+ * {@link #entries} array. The hash array is interpreted as an actual byte array if the indices fit
+ * within 8 bit, or as an array of short values if the indices fit within 16 bit, or as an array of
+ * integer values in other cases.
+ *
+ * Hash collisions are handled by chaining a linked list of {@link CollisionLink} objects that take
+ * the place of the values in the {@link #entries} array.
+ *
+ * Removing entries will put {@code null} into the {@link #entries} array. If the occupation of the
+ * map falls below a specific threshold, the map will be compressed via the
+ * {@link #maybeCompress(int)} method.
+ */
+final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> {
+
+    /**
+     * Initial number of key/value pair entries that is allocated in the first entries array.
+     */
+    private static final int INITIAL_CAPACITY = 4;
+
+    /**
+     * Maximum number of entries that are moved linearly forward if a key is removed.
+     */
+    private static final int COMPRESS_IMMEDIATE_CAPACITY = 8;
+
+    /**
+     * Minimum number of key/value pair entries added when the entries array is increased in size.
+     */
+    private static final int MIN_CAPACITY_INCREASE = 8;
+
+    /**
+     * Number of entries above which a hash table is created.
+     */
+    private static final int HASH_THRESHOLD = 4;
+
+    /**
+     * Number of entries above which a hash table is created when equality can be checked with
+     * object identity.
+     */
+    private static final int HASH_THRESHOLD_IDENTITY_COMPARE = 8;
+
+    /**
+     * Maximum number of entries allowed in the map.
+     */
+    private static final int MAX_ELEMENT_COUNT = Integer.MAX_VALUE >> 1;
+
+    /**
+     * Number of entries above which more than 1 byte is necessary for the hash index.
+     */
+    private static final int LARGE_HASH_THRESHOLD = ((1 << Byte.SIZE) << 1);
+
+    /**
+     * Number of entries above which more than 2 bytes are are necessary for the hash index.
+     */
+    private static final int VERY_LARGE_HASH_THRESHOLD = (LARGE_HASH_THRESHOLD << Byte.SIZE);
+
+    /**
+     * Total number of entries (actual entries plus deleted entries).
+     */
+    private int totalEntries;
+
+    /**
+     * Number of deleted entries.
+     */
+    private int deletedEntries;
+
+    /**
+     * Entries array with even indices storing keys and odd indices storing values.
+     */
+    private Object[] entries;
+
+    /**
+     * Hash array that is interpreted either as byte or short or int array depending on number of
+     * map entries.
+     */
+    private byte[] hashArray;
+
+    /**
+     * The strategy used for comparing keys or {@code null} for denoting special strategy
+     * {@link Equivalence#IDENTITY}.
+     */
+    private final Equivalence strategy;
+
+    /**
+     * Intercept method for debugging purposes.
+     */
+    private static <K, V> EconomicMapImpl<K, V> intercept(EconomicMapImpl<K, V> map) {
+        return map;
+    }
+
+    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, boolean isSet) {
+        return intercept(new EconomicMapImpl<>(strategy, isSet));
+    }
+
+    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity, boolean isSet) {
+        return intercept(new EconomicMapImpl<>(strategy, initialCapacity, isSet));
+    }
+
+    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
+        return intercept(new EconomicMapImpl<>(strategy, other, isSet));
+    }
+
+    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
+        return intercept(new EconomicMapImpl<>(strategy, other, isSet));
+    }
+
+    private EconomicMapImpl(Equivalence strategy, boolean isSet) {
+        if (strategy == Equivalence.IDENTITY) {
+            this.strategy = null;
+        } else {
+            this.strategy = strategy;
+        }
+        this.isSet = isSet;
+    }
+
+    private EconomicMapImpl(Equivalence strategy, int initialCapacity, boolean isSet) {
+        this(strategy, isSet);
+        init(initialCapacity);
+    }
+
+    private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
+        this(strategy, isSet);
+        if (!initFrom(other)) {
+            init(other.size());
+            putAll(other);
+        }
+    }
+
+    private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
+        this(strategy, isSet);
+        if (!initFrom(other)) {
+            init(other.size());
+            addAll(other);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private boolean initFrom(Object o) {
+        if (o instanceof EconomicMapImpl) {
+            EconomicMapImpl<K, V> otherMap = (EconomicMapImpl<K, V>) o;
+            // We are only allowed to directly copy if the strategies of the two maps are the same.
+            if (strategy == otherMap.strategy) {
+                totalEntries = otherMap.totalEntries;
+                deletedEntries = otherMap.deletedEntries;
+                if (otherMap.entries != null) {
+                    entries = otherMap.entries.clone();
+                }
+                if (otherMap.hashArray != null) {
+                    hashArray = otherMap.hashArray.clone();
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void init(int size) {
+        if (size > INITIAL_CAPACITY) {
+            entries = new Object[size << 1];
+        }
+    }
+
+    /**
+     * Links the collisions. Needs to be immutable class for allowing efficient shallow copy from
+     * other map on construction.
+     */
+    private static final class CollisionLink {
+
+        CollisionLink(Object value, int next) {
+            this.value = value;
+            this.next = next;
+        }
+
+        final Object value;
+
+        /**
+         * Index plus one of the next entry in the collision link chain.
+         */
+        final int next;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public V get(K key) {
+        Objects.requireNonNull(key);
+
+        int index = find(key);
+        if (index != -1) {
+            return (V) getValue(index);
+        }
+        return null;
+    }
+
+    private int find(K key) {
+        if (hasHashArray()) {
+            return findHash(key);
+        } else {
+            return findLinear(key);
+        }
+    }
+
+    private int findLinear(K key) {
+        for (int i = 0; i < totalEntries; i++) {
+            Object entryKey = entries[i << 1];
+            if (entryKey != null && compareKeys(key, entryKey)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private boolean compareKeys(Object key, Object entryKey) {
+        if (key == entryKey) {
+            return true;
+        }
+        if (strategy != null && strategy != Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
+            if (strategy == Equivalence.DEFAULT) {
+                return key.equals(entryKey);
+            } else {
+                return strategy.equals(key, entryKey);
+            }
+        }
+        return false;
+    }
+
+    private int findHash(K key) {
+        int index = getHashArray(getHashIndex(key)) - 1;
+        if (index != -1) {
+            Object entryKey = getKey(index);
+            if (compareKeys(key, entryKey)) {
+                return index;
+            } else {
+                Object entryValue = getRawValue(index);
+                if (entryValue instanceof CollisionLink) {
+                    return findWithCollision(key, (CollisionLink) entryValue);
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    private int findWithCollision(K key, CollisionLink initialEntryValue) {
+        int index;
+        Object entryKey;
+        CollisionLink entryValue = initialEntryValue;
+        while (true) {
+            CollisionLink collisionLink = entryValue;
+            index = collisionLink.next;
+            entryKey = getKey(index);
+            if (compareKeys(key, entryKey)) {
+                return index;
+            } else {
+                Object value = getRawValue(index);
+                if (value instanceof CollisionLink) {
+                    entryValue = (CollisionLink) getRawValue(index);
+                } else {
+                    return -1;
+                }
+            }
+        }
+    }
+
+    private int getHashArray(int index) {
+        if (entries.length < LARGE_HASH_THRESHOLD) {
+            return (hashArray[index] & 0xFF);
+        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
+            int adjustedIndex = index << 1;
+            return (hashArray[adjustedIndex] & 0xFF) | ((hashArray[adjustedIndex + 1] & 0xFF) << 8);
+        } else {
+            int adjustedIndex = index << 2;
+            return (hashArray[adjustedIndex] & 0xFF) | ((hashArray[adjustedIndex + 1] & 0xFF) << 8) | ((hashArray[adjustedIndex + 2] & 0xFF) << 16) | ((hashArray[adjustedIndex + 3] & 0xFF) << 24);
+        }
+    }
+
+    private void setHashArray(int index, int value) {
+        if (entries.length < LARGE_HASH_THRESHOLD) {
+            hashArray[index] = (byte) value;
+        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
+            int adjustedIndex = index << 1;
+            hashArray[adjustedIndex] = (byte) value;
+            hashArray[adjustedIndex + 1] = (byte) (value >> 8);
+        } else {
+            int adjustedIndex = index << 2;
+            hashArray[adjustedIndex] = (byte) value;
+            hashArray[adjustedIndex + 1] = (byte) (value >> 8);
+            hashArray[adjustedIndex + 2] = (byte) (value >> 16);
+            hashArray[adjustedIndex + 3] = (byte) (value >> 24);
+        }
+    }
+
+    private int findAndRemoveHash(Object key) {
+        int hashIndex = getHashIndex(key);
+        int index = getHashArray(hashIndex) - 1;
+        if (index != -1) {
+            Object entryKey = getKey(index);
+            if (compareKeys(key, entryKey)) {
+                Object value = getRawValue(index);
+                int nextIndex = -1;
+                if (value instanceof CollisionLink) {
+                    CollisionLink collisionLink = (CollisionLink) value;
+                    nextIndex = collisionLink.next;
+                }
+                setHashArray(hashIndex, nextIndex + 1);
+                return index;
+            } else {
+                Object entryValue = getRawValue(index);
+                if (entryValue instanceof CollisionLink) {
+                    return findAndRemoveWithCollision(key, (CollisionLink) entryValue, index);
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    private int findAndRemoveWithCollision(Object key, CollisionLink initialEntryValue, int initialIndexValue) {
+        int index;
+        Object entryKey;
+        CollisionLink entryValue = initialEntryValue;
+        int lastIndex = initialIndexValue;
+        while (true) {
+            CollisionLink collisionLink = entryValue;
+            index = collisionLink.next;
+            entryKey = getKey(index);
+            if (compareKeys(key, entryKey)) {
+                Object value = getRawValue(index);
+                if (value instanceof CollisionLink) {
+                    CollisionLink thisCollisionLink = (CollisionLink) value;
+                    setRawValue(lastIndex, new CollisionLink(collisionLink.value, thisCollisionLink.next));
+                } else {
+                    setRawValue(lastIndex, collisionLink.value);
+                }
+                return index;
+            } else {
+                Object value = getRawValue(index);
+                if (value instanceof CollisionLink) {
+                    entryValue = (CollisionLink) getRawValue(index);
+                    lastIndex = index;
+                } else {
+                    return -1;
+                }
+            }
+        }
+    }
+
+    private int getHashIndex(Object key) {
+        int hash;
+        if (strategy != null && strategy != Equivalence.DEFAULT) {
+            if (strategy == Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
+                hash = System.identityHashCode(key);
+            } else {
+                hash = strategy.hashCode(key);
+            }
+        } else {
+            hash = key.hashCode();
+        }
+        hash = hash ^ (hash >>> 16);
+        return hash & (getHashTableSize() - 1);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public V put(K key, V value) {
+        if (key == null) {
+            throw new UnsupportedOperationException("null not supported as key!");
+        }
+        int index = find(key);
+        if (index != -1) {
+            Object oldValue = getValue(index);
+            setValue(index, value);
+            return (V) oldValue;
+        }
+
+        int nextEntryIndex = totalEntries;
+        if (entries == null) {
+            entries = new Object[INITIAL_CAPACITY << 1];
+        } else if (entries.length == nextEntryIndex << 1) {
+            grow();
+
+            assert entries.length > totalEntries << 1;
+            // Can change if grow is actually compressing.
+            nextEntryIndex = totalEntries;
+        }
+
+        setKey(nextEntryIndex, key);
+        setValue(nextEntryIndex, value);
+        totalEntries++;
+
+        if (hasHashArray()) {
+            // Rehash on collision if hash table is more than three quarters full.
+            boolean rehashOnCollision = (getHashTableSize() < (size() + (size() >> 1)));
+            putHashEntry(key, nextEntryIndex, rehashOnCollision);
+        } else if (totalEntries > getHashThreshold()) {
+            createHash();
+        }
+
+        return null;
+    }
+
+    /**
+     * Number of entries above which a hash table should be constructed.
+     */
+    private int getHashThreshold() {
+        if (strategy == null || strategy == Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
+            return HASH_THRESHOLD_IDENTITY_COMPARE;
+        } else {
+            return HASH_THRESHOLD;
+        }
+    }
+
+    private void grow() {
+        int entriesLength = entries.length;
+        int newSize = (entriesLength >> 1) + Math.max(MIN_CAPACITY_INCREASE, entriesLength >> 2);
+        if (newSize > MAX_ELEMENT_COUNT) {
+            throw new UnsupportedOperationException("map grown too large!");
+        }
+        Object[] newEntries = new Object[newSize << 1];
+        System.arraycopy(entries, 0, newEntries, 0, entriesLength);
+        entries = newEntries;
+        if ((entriesLength < LARGE_HASH_THRESHOLD && newEntries.length >= LARGE_HASH_THRESHOLD) ||
+                        (entriesLength < VERY_LARGE_HASH_THRESHOLD && newEntries.length > VERY_LARGE_HASH_THRESHOLD)) {
+            // Rehash in order to change number of bits reserved for hash indices.
+            createHash();
+        }
+    }
+
+    /**
+     * Compresses the graph if there is a large number of deleted entries and returns the translated
+     * new next index.
+     */
+    private int maybeCompress(int nextIndex) {
+        if (entries.length != INITIAL_CAPACITY << 1 && deletedEntries >= (totalEntries >> 1) + (totalEntries >> 2)) {
+            return compressLarge(nextIndex);
+        }
+        return nextIndex;
+    }
+
+    /**
+     * Compresses the graph and returns the translated new next index.
+     */
+    private int compressLarge(int nextIndex) {
+        int size = INITIAL_CAPACITY;
+        int remaining = totalEntries - deletedEntries;
+
+        while (size <= remaining) {
+            size += Math.max(MIN_CAPACITY_INCREASE, size >> 1);
+        }
+
+        Object[] newEntries = new Object[size << 1];
+        int z = 0;
+        int newNextIndex = remaining;
+        for (int i = 0; i < totalEntries; ++i) {
+            Object key = getKey(i);
+            if (i == nextIndex) {
+                newNextIndex = z;
+            }
+            if (key != null) {
+                newEntries[z << 1] = key;
+                newEntries[(z << 1) + 1] = getValue(i);
+                z++;
+            }
+        }
+
+        this.entries = newEntries;
+        totalEntries = z;
+        deletedEntries = 0;
+        if (z <= getHashThreshold()) {
+            this.hashArray = null;
+        } else {
+            createHash();
+        }
+        return newNextIndex;
+    }
+
+    private int getHashTableSize() {
+        if (entries.length < LARGE_HASH_THRESHOLD) {
+            return hashArray.length;
+        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
+            return hashArray.length >> 1;
+        } else {
+            return hashArray.length >> 2;
+        }
+    }
+
+    private void createHash() {
+        int entryCount = size();
+
+        // Calculate smallest 2^n that is greater number of entries.
+        int size = getHashThreshold();
+        while (size <= entryCount) {
+            size <<= 1;
+        }
+
+        // Give extra size to avoid collisions.
+        size <<= 1;
+
+        if (this.entries.length >= VERY_LARGE_HASH_THRESHOLD) {
+            // Every entry has 4 bytes.
+            size <<= 2;
+        } else if (this.entries.length >= LARGE_HASH_THRESHOLD) {
+            // Every entry has 2 bytes.
+            size <<= 1;
+        } else {
+            // Entries are very small => give extra size to further reduce collisions.
+            size <<= 1;
+        }
+
+        hashArray = new byte[size];
+        for (int i = 0; i < totalEntries; i++) {
+            Object entryKey = getKey(i);
+            if (entryKey != null) {
+                putHashEntry(entryKey, i, false);
+            }
+        }
+    }
+
+    private void putHashEntry(Object key, int entryIndex, boolean rehashOnCollision) {
+        int hashIndex = getHashIndex(key);
+        int oldIndex = getHashArray(hashIndex) - 1;
+        if (oldIndex != -1 && rehashOnCollision) {
+            this.createHash();
+            return;
+        }
+        setHashArray(hashIndex, entryIndex + 1);
+        Object value = getRawValue(entryIndex);
+        if (oldIndex != -1) {
+            assert entryIndex != oldIndex : "this cannot happend and would create an endless collision link cycle";
+            if (value instanceof CollisionLink) {
+                CollisionLink collisionLink = (CollisionLink) value;
+                setRawValue(entryIndex, new CollisionLink(collisionLink.value, oldIndex));
+            } else {
+                setRawValue(entryIndex, new CollisionLink(getRawValue(entryIndex), oldIndex));
+            }
+        } else {
+            if (value instanceof CollisionLink) {
+                CollisionLink collisionLink = (CollisionLink) value;
+                setRawValue(entryIndex, collisionLink.value);
+            }
+        }
+    }
+
+    @Override
+    public int size() {
+        return totalEntries - deletedEntries;
+    }
+
+    @Override
+    public boolean containsKey(K key) {
+        return find(key) != -1;
+    }
+
+    @Override
+    public void clear() {
+        entries = null;
+        hashArray = null;
+        totalEntries = deletedEntries = 0;
+    }
+
+    private boolean hasHashArray() {
+        return hashArray != null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public V removeKey(K key) {
+        if (key == null) {
+            throw new UnsupportedOperationException("null not supported as key!");
+        }
+        int index;
+        if (hasHashArray()) {
+            index = this.findAndRemoveHash(key);
+        } else {
+            index = this.findLinear(key);
+        }
+
+        if (index != -1) {
+            Object value = getValue(index);
+            remove(index);
+            return (V) value;
+        }
+        return null;
+    }
+
+    /**
+     * Removes the element at the specific index and returns the index of the next element. This can
+     * be a different value if graph compression was triggered.
+     */
+    private int remove(int indexToRemove) {
+        int index = indexToRemove;
+        int entriesAfterIndex = totalEntries - index - 1;
+        int result = index + 1;
+
+        // Without hash array, compress immediately.
+        if (entriesAfterIndex <= COMPRESS_IMMEDIATE_CAPACITY && !hasHashArray()) {
+            while (index < totalEntries - 1) {
+                setKey(index, getKey(index + 1));
+                setRawValue(index, getRawValue(index + 1));
+                index++;
+            }
+            result--;
+        }
+
+        setKey(index, null);
+        setRawValue(index, null);
+        if (index == totalEntries - 1) {
+            // Make sure last element is always non-null.
+            totalEntries--;
+            while (index > 0 && getKey(index - 1) == null) {
+                totalEntries--;
+                deletedEntries--;
+                index--;
+            }
+        } else {
+            deletedEntries++;
+            result = maybeCompress(result);
+        }
+
+        return result;
+    }
+
+    private abstract class SparseMapIterator<E> implements Iterator<E> {
+
+        protected int current;
+
+        @Override
+        public boolean hasNext() {
+            return current < totalEntries;
+        }
+
+        @Override
+        public void remove() {
+            if (hasHashArray()) {
+                EconomicMapImpl.this.findAndRemoveHash(getKey(current - 1));
+            }
+            current = EconomicMapImpl.this.remove(current - 1);
+        }
+    }
+
+    @Override
+    public Iterable<V> getValues() {
+        return new Iterable<V>() {
+            @Override
+            public Iterator<V> iterator() {
+                return new SparseMapIterator<V>() {
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public V next() {
+                        Object result;
+                        while (true) {
+                            result = getValue(current);
+                            if (result == null && getKey(current) == null) {
+                                // values can be null, double-check if key is also null
+                                current++;
+                            } else {
+                                current++;
+                                break;
+                            }
+                        }
+                        return (V) result;
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public Iterable<K> getKeys() {
+        return this;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return this.size() == 0;
+    }
+
+    @Override
+    public MapCursor<K, V> getEntries() {
+        return new MapCursor<K, V>() {
+            int current = -1;
+
+            @Override
+            public boolean advance() {
+                current++;
+                if (current >= totalEntries) {
+                    return false;
+                } else {
+                    while (EconomicMapImpl.this.getKey(current) == null) {
+                        // Skip over null entries
+                        current++;
+                    }
+                    return true;
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public K getKey() {
+                return (K) EconomicMapImpl.this.getKey(current);
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public V getValue() {
+                return (V) EconomicMapImpl.this.getValue(current);
+            }
+
+            @Override
+            public void remove() {
+                if (hasHashArray()) {
+                    EconomicMapImpl.this.findAndRemoveHash(EconomicMapImpl.this.getKey(current));
+                }
+                current = EconomicMapImpl.this.remove(current) - 1;
+            }
+        };
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        for (int i = 0; i < totalEntries; i++) {
+            Object entryKey = getKey(i);
+            if (entryKey != null) {
+                Object newValue = function.apply((K) entryKey, (V) getValue(i));
+                setValue(i, newValue);
+            }
+        }
+    }
+
+    private Object getKey(int index) {
+        return entries[index << 1];
+    }
+
+    private void setKey(int index, Object newValue) {
+        entries[index << 1] = newValue;
+    }
+
+    private void setValue(int index, Object newValue) {
+        Object oldValue = getRawValue(index);
+        if (oldValue instanceof CollisionLink) {
+            CollisionLink collisionLink = (CollisionLink) oldValue;
+            setRawValue(index, new CollisionLink(newValue, collisionLink.next));
+        } else {
+            setRawValue(index, newValue);
+        }
+    }
+
+    private void setRawValue(int index, Object newValue) {
+        entries[(index << 1) + 1] = newValue;
+    }
+
+    private Object getRawValue(int index) {
+        return entries[(index << 1) + 1];
+    }
+
+    private Object getValue(int index) {
+        Object object = getRawValue(index);
+        if (object instanceof CollisionLink) {
+            return ((CollisionLink) object).value;
+        }
+        return object;
+    }
+
+    private final boolean isSet;
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(isSet ? "set(size=" : "map(size=").append(size()).append(", {");
+        String sep = "";
+        MapCursor<K, V> cursor = getEntries();
+        while (cursor.advance()) {
+            builder.append(sep);
+            if (isSet) {
+                builder.append(cursor.getKey());
+            } else {
+                builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append(")");
+            }
+            sep = ",";
+        }
+        builder.append("})");
+        return builder.toString();
+    }
+
+    @Override
+    public Iterator<K> iterator() {
+        return new SparseMapIterator<K>() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public K next() {
+                Object result;
+                while ((result = getKey(current++)) == null) {
+                    // skip null entries
+                }
+                return (K) result;
+            }
+        };
+    }
+
+    @Override
+    public boolean contains(K element) {
+        return containsKey(element);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean add(K element) {
+        return put(element, (V) element) == null;
+    }
+
+    @Override
+    public void remove(K element) {
+        removeKey(element);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+import java.util.Iterator;
+
+/**
+ * Memory efficient set data structure.
+ *
+ * @since 1.0
+ */
+public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
+
+    /**
+     * Adds {@code element} to this set if it is not already present.
+     *
+     * @return {@code true} if this set did not already contain {@code element}.
+     * @since 1.0
+     */
+    boolean add(E element);
+
+    /**
+     * Removes {@code element} from this set if it is present. This set will not contain
+     * {@code element} once the call returns.
+     *
+     * @since 1.0
+     */
+    void remove(E element);
+
+    /**
+     * Removes all of the elements from this set. The set will be empty after this call returns.
+     *
+     * @since 1.0
+     */
+    void clear();
+
+    /**
+     * Adds all of the elements in {@code other} to this set if they're not already present.
+     *
+     * @since 1.0
+     */
+    default void addAll(EconomicSet<E> other) {
+        addAll(other.iterator());
+    }
+
+    /**
+     * Adds all of the elements in {@code values} to this set if they're not already present.
+     *
+     * @since 1.0
+     */
+    default void addAll(Iterable<E> values) {
+        addAll(values.iterator());
+    }
+
+    /**
+     * Adds all of the elements enumerated by {@code iterator} to this set if they're not already
+     * present.
+     *
+     * @since 1.0
+     */
+    default void addAll(Iterator<E> iterator) {
+        while (iterator.hasNext()) {
+            add(iterator.next());
+        }
+    }
+
+    /**
+     * Removes from this set all of its elements that are contained in {@code other}.
+     *
+     * @since 1.0
+     */
+    default void removeAll(EconomicSet<E> other) {
+        removeAll(other.iterator());
+    }
+
+    /**
+     * Removes from this set all of its elements that are contained in {@code values}.
+     *
+     * @since 1.0
+     */
+    default void removeAll(Iterable<E> values) {
+        removeAll(values.iterator());
+    }
+
+    /**
+     * Removes from this set all of its elements that are enumerated by {@code iterator}.
+     *
+     * @since 1.0
+     */
+    default void removeAll(Iterator<E> iterator) {
+        while (iterator.hasNext()) {
+            remove(iterator.next());
+        }
+    }
+
+    /**
+     * Removes from this set all of its elements that are not contained in {@code other}.
+     *
+     * @since 1.0
+     */
+    default void retainAll(EconomicSet<E> other) {
+        Iterator<E> iterator = iterator();
+        while (iterator.hasNext()) {
+            E key = iterator.next();
+            if (!other.contains(key)) {
+                iterator.remove();
+            }
+        }
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements with the
+     * default {@link Equivalence#DEFAULT} comparison strategy.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create() {
+        return EconomicSet.create(Equivalence.DEFAULT);
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create(Equivalence strategy) {
+        return EconomicMapImpl.create(strategy, true);
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements with the
+     * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
+     * specified collection.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create(int initialCapacity) {
+        return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements with the
+     * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
+     * specified collection.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
+        return EconomicSet.create(Equivalence.DEFAULT, c);
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements and
+     * initializes with the given capacity.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
+        return EconomicMapImpl.create(strategy, initialCapacity, true);
+    }
+
+    /**
+     * Creates a new set guaranteeing insertion order when iterating over its elements and inserts
+     * all elements of the specified collection.
+     *
+     * @since 1.0
+     */
+    static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
+        return EconomicMapImpl.create(strategy, c, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+/**
+ * Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
+ * {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
+ *
+ * @since 1.0
+ */
+public abstract class Equivalence {
+
+    /**
+     * Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()}
+     * for obtaining hash values. Do not change the logic of this class as it may be inlined in
+     * other places.
+     *
+     * @since 1.0
+     */
+    public static final Equivalence DEFAULT = new Equivalence() {
+
+        @Override
+        public boolean equals(Object a, Object b) {
+            return a.equals(b);
+        }
+
+        @Override
+        public int hashCode(Object o) {
+            return o.hashCode();
+        }
+    };
+
+    /**
+     * Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
+     * hash values. Do not change the logic of this class as it may be inlined in other places.
+     *
+     * @since 1.0
+     */
+    public static final Equivalence IDENTITY = new Equivalence() {
+
+        @Override
+        public boolean equals(Object a, Object b) {
+            return a == b;
+        }
+
+        @Override
+        public int hashCode(Object o) {
+            return o.hashCode();
+        }
+    };
+
+    /**
+     * Identity equivalence using {@code ==} to check equality and
+     * {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
+     * this class as it may be inlined in other places.
+     *
+     * @since 1.0
+     */
+    public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
+
+        @Override
+        public boolean equals(Object a, Object b) {
+            return a == b;
+        }
+
+        @Override
+        public int hashCode(Object o) {
+            return System.identityHashCode(o);
+        }
+    };
+
+    /**
+     * Subclass for creating custom equivalence definitions.
+     *
+     * @since 1.0
+     */
+    protected Equivalence() {
+    }
+
+    /**
+     * Returns {@code true} if the non-{@code null} arguments are equal to each other and
+     * {@code false} otherwise.
+     *
+     * @since 1.0
+     */
+    public abstract boolean equals(Object a, Object b);
+
+    /**
+     * Returns the hash code of a non-{@code null} argument {@code o}.
+     *
+     * @since 1.0
+     */
+    public abstract int hashCode(Object o);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+/**
+ * Cursor to iterate over a mutable map.
+ *
+ * @since 1.0
+ */
+public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
+    /**
+     * Remove the current entry from the map. May only be called once. After calling
+     * {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
+     * the current entry.
+     *
+     * @since 1.0
+     */
+    void remove();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+import java.util.Objects;
+
+/**
+ * Utility class representing a pair of values.
+ *
+ * @since 1.0
+ */
+public final class Pair<L, R> {
+
+    private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
+
+    private final L left;
+    private final R right;
+
+    /**
+     * Returns an empty pair.
+     *
+     * @since 1.0
+     */
+    @SuppressWarnings("unchecked")
+    public static <L, R> Pair<L, R> empty() {
+        return (Pair<L, R>) EMPTY;
+    }
+
+    /**
+     * Constructs a pair with its left value being {@code left}, or returns an empty pair if
+     * {@code left} is null.
+     *
+     * @return the constructed pair or an empty pair if {@code left} is null.
+     * @since 1.0
+     */
+    public static <L, R> Pair<L, R> createLeft(L left) {
+        if (left == null) {
+            return empty();
+        } else {
+            return new Pair<>(left, null);
+        }
+    }
+
+    /**
+     * Constructs a pair with its right value being {@code right}, or returns an empty pair if
+     * {@code right} is null.
+     *
+     * @return the constructed pair or an empty pair if {@code right} is null.
+     * @since 1.0
+     */
+    public static <L, R> Pair<L, R> createRight(R right) {
+        if (right == null) {
+            return empty();
+        } else {
+            return new Pair<>(null, right);
+        }
+    }
+
+    /**
+     * Constructs a pair with its left value being {@code left}, and its right value being
+     * {@code right}, or returns an empty pair if both inputs are null.
+     *
+     * @return the constructed pair or an empty pair if both inputs are null.
+     * @since 1.0
+     */
+    public static <L, R> Pair<L, R> create(L left, R right) {
+        if (right == null && left == null) {
+            return empty();
+        } else {
+            return new Pair<>(left, right);
+        }
+    }
+
+    private Pair(L left, R right) {
+        this.left = left;
+        this.right = right;
+    }
+
+    /**
+     * Returns the left value of this pair.
+     *
+     * @since 1.0
+     */
+    public L getLeft() {
+        return left;
+    }
+
+    /**
+     * Returns the right value of this pair.
+     *
+     * @since 1.0
+     */
+    public R getRight() {
+        return right;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 1.0
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(left) + 31 * Objects.hashCode(right);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 1.0
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj instanceof Pair) {
+            Pair<L, R> pair = (Pair<L, R>) obj;
+            return Objects.equals(left, pair.left) && Objects.equals(right, pair.right);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 1.0
+     */
+    @Override
+    public String toString() {
+        return String.format("(%s, %s)", left, right);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+/**
+ * Unmodifiable memory efficient map data structure.
+ *
+ * @since 1.0
+ */
+public interface UnmodifiableEconomicMap<K, V> {
+
+    /**
+     * Returns the value to which {@code key} is mapped, or {@code null} if this map contains no
+     * mapping for {@code key}.
+     *
+     * @since 1.0
+     */
+    V get(K key);
+
+    /**
+     * Returns the value to which {@code key} is mapped, or {@code defaultValue} if this map
+     * contains no mapping for {@code key}.
+     *
+     * @since 1.0
+     */
+    default V get(K key, V defaultValue) {
+        V v = get(key);
+        if (v == null) {
+            return defaultValue;
+        }
+        return v;
+    }
+
+    /**
+     * Returns {@code true} if this map contains a mapping for {@code key}.
+     *
+     * @since 1.0
+     */
+    boolean containsKey(K key);
+
+    /**
+     * Returns the number of key-value mappings in this map.
+     *
+     * @since 1.0
+     */
+    int size();
+
+    /**
+     * Returns {@code true} if this map contains no key-value mappings.
+     *
+     * @since 1.0
+     */
+    boolean isEmpty();
+
+    /**
+     * Returns a {@link Iterable} view of the values contained in this map.
+     *
+     * @since 1.0
+     */
+    Iterable<V> getValues();
+
+    /**
+     * Returns a {@link Iterable} view of the keys contained in this map.
+     *
+     * @since 1.0
+     */
+    Iterable<K> getKeys();
+
+    /**
+     * Returns a {@link UnmodifiableMapCursor} view of the mappings contained in this map.
+     *
+     * @since 1.0
+     */
+    UnmodifiableMapCursor<K, V> getEntries();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+/**
+ * Unmodifiable memory efficient set data structure.
+ *
+ * @since 1.0
+ */
+public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
+
+    /**
+     * Returns {@code true} if this set contains a mapping for the {@code element}.
+     *
+     * @since 1.0
+     */
+    boolean contains(E element);
+
+    /**
+     * Returns the number of elements in this set.
+     *
+     * @since 1.0
+     */
+    int size();
+
+    /**
+     * Returns {@code true} if this set contains no elements.
+     *
+     * @since 1.0
+     */
+    boolean isEmpty();
+
+    /**
+     * Stores all of the elements in this set into {@code target}. An
+     * {@link UnsupportedOperationException} will be thrown if the length of {@code target} does not
+     * match the size of this set.
+     *
+     * @return an array containing all the elements in this set.
+     * @throws UnsupportedOperationException if the length of {@code target} does not equal the size
+     *             of this set.
+     * @since 1.0
+     */
+    default E[] toArray(E[] target) {
+        if (target.length != size()) {
+            throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
+        }
+
+        int index = 0;
+        for (E element : this) {
+            target[index++] = element;
+        }
+
+        return target;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.collections;
+
+/**
+ * Cursor to iterate over a map without changing its contents.
+ *
+ * @since 1.0
+ */
+public interface UnmodifiableMapCursor<K, V> {
+    /**
+     * Advances to the next entry.
+     *
+     * @return {@code true} if a next entry exists, {@code false} if there is no next entry.
+     * @since 1.0
+     */
+    boolean advance();
+
+    /**
+     * The key of the current entry.
+     *
+     * @since 1.0
+     */
+    K getKey();
+
+    /**
+     * The value of the current entry.
+     *
+     * @since 1.0
+     */
+    V getValue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+/*
+ @ApiInfo(
+ group="Graal SDK"
+ )
+ */
+/**
+ * The Graal-SDK collections package contains memory efficient data structures.
+ *
+ * @see jdk.internal.vm.compiler.collections.EconomicMap
+ * @see jdk.internal.vm.compiler.collections.EconomicSet
+ *
+ * @since 1.0
+ */
+package jdk.internal.vm.compiler.collections;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,53 @@
+/*
+ * 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 jdk.internal.vm.compiler.word;
+
+/**
+ * A machine-word-sized value that can be compared for equality.
+ *
+ * @since 1.0
+ */
+public interface ComparableWord extends WordBase {
+
+    /**
+     * Compares this word with the specified value.
+     *
+     * @param val value to which this word is to be compared.
+     * @return {@code this == val}
+     *
+     * @since 1.0
+     */
+    boolean equal(ComparableWord val);
+
+    /**
+     * Compares this word with the specified value.
+     *
+     * @param val value to which this word is to be compared.
+     * @return {@code this != val}
+     *
+     * @since 1.0
+     */
+    boolean notEqual(ComparableWord val);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word;
+
+// JaCoCo Exclude
+
+/**
+ * Marker interface for location identities. A different location identity of two memory accesses
+ * guarantees that the two accesses do not interfere.
+ * <p>
+ * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
+ * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
+ * {@link java.util.IdentityHashMap}s with {@link LocationIdentity} values as keys.
+ *
+ * @since 1.0
+ */
+public abstract class LocationIdentity {
+
+    private static final class AnyLocationIdentity extends LocationIdentity {
+        @Override
+        public boolean isImmutable() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ANY_LOCATION";
+        }
+    }
+
+    private static final class InitLocationIdentity extends LocationIdentity {
+        @Override
+        public boolean isImmutable() {
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            return "INIT_LOCATION";
+        }
+    }
+
+    /**
+     * Creates a new location identity. Subclasses are responsible to provide proper implementations
+     * of {@link #equals} and {@link #hashCode}.
+     *
+     * @since 1.0
+     */
+    protected LocationIdentity() {
+    }
+
+    /**
+     * Indicates that the given location is the union of all possible mutable locations. A write to
+     * such a location kill all reads from mutable locations and a read from this location is killed
+     * by any write (except for initialization writes).
+     *
+     * @since 1.0
+     */
+    public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
+
+    /**
+     * Location only allowed to be used for writes. Indicates that a completely new memory location
+     * is written. Kills no read. The previous value at the given location must be either
+     * uninitialized or null. Writes to this location do not need a GC pre-barrier.
+     *
+     * @since 1.0
+     */
+    public static final LocationIdentity INIT_LOCATION = new InitLocationIdentity();
+
+    /**
+     * Indicates that the given location is the union of all possible mutable locations. A write to
+     * such a location kill all reads from mutable locations and a read from this location is killed
+     * by any write (except for initialization writes).
+     *
+     * @since 1.0
+     */
+    public static LocationIdentity any() {
+        return ANY_LOCATION;
+    }
+
+    /**
+     * Location only allowed to be used for writes. Indicates that a completely new memory location
+     * is written. Kills no read. The previous value at the given location must be either
+     * uninitialized or null. Writes to this location do not need a GC pre-barrier.
+     *
+     * @since 1.0
+     */
+    public static LocationIdentity init() {
+        return INIT_LOCATION;
+    }
+
+    /**
+     * Denotes a location is unchanging in all cases. Not that this is different than the Java
+     * notion of final which only requires definite assignment.
+     *
+     * @since 1.0
+     */
+    public abstract boolean isImmutable();
+
+    /**
+     * The inversion of {@link #isImmutable}.
+     *
+     * @since 1.0
+     */
+    public final boolean isMutable() {
+        return !isImmutable();
+    }
+
+    /**
+     * Returns true if this location identity is {@link #any}.
+     *
+     * @since 1.0
+     */
+    public final boolean isAny() {
+        return this == ANY_LOCATION;
+    }
+
+    /**
+     * Returns true if this location identity is {@link #init}.
+     *
+     * @since 1.0
+     */
+    public final boolean isInit() {
+        return this == INIT_LOCATION;
+    }
+
+    /**
+     * Returns true if this location identity is not {@link #any}.
+     *
+     * @since 1.0
+     */
+    public final boolean isSingle() {
+        return this != ANY_LOCATION;
+    }
+
+    /**
+     * Returns true if the memory slice denoted by this location identity may overlap with the
+     * provided other location identity.
+     *
+     * @since 1.0
+     */
+    public final boolean overlaps(LocationIdentity other) {
+        return isAny() || other.isAny() || this.equals(other);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,1415 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word;
+
+/**
+ * Lowest-level memory access of native C memory.
+ * <p>
+ * Do not use these methods to access Java objects. These methods access the raw memory without any
+ * null checks, read- or write barriers. Even when the VM uses compressed pointers, then readObject
+ * and writeObject methods access uncompressed pointers.
+ *
+ * @since 1.0
+ */
+public interface Pointer extends UnsignedWord, PointerBase {
+
+    /**
+     * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type
+     * checks are performed. The caller must ensure that the Pointer contains a valid Java object
+     * that can i.e., processed by the garbage collector.
+     *
+     * @return this Pointer cast to Object.
+     *
+     * @since 1.0
+     */
+    Object toObject();
+
+    /**
+     * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type
+     * checks are performed. The caller must ensure that the Pointer contains a valid Java object
+     * that can i.e., processed by the garbage collector and the Pointer does not contain 0.
+     *
+     * @return this Pointer cast to non-null Object.
+     *
+     * @since 1.0
+     */
+    Object toObjectNonNull();
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    byte readByte(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    char readChar(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    short readShort(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    int readInt(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    long readLong(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    float readFloat(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    double readDouble(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T readWord(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    Object readObject(WordBase offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    byte readByte(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    char readChar(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    short readShort(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    int readInt(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    long readLong(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    float readFloat(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    double readDouble(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the read
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    Object readObject(int offset, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeChar(WordBase offset, char val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeShort(WordBase offset, short val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeInt(WordBase offset, int val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeLong(WordBase offset, long val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity);
+
+    /**
+     * Initializes the memory at address {@code (this + offset)}. Both the base address and offset
+     * are in bytes. The memory must be uninitialized or zero prior to this operation.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeByte(int offset, byte val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeChar(int offset, char val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeShort(int offset, short val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeInt(int offset, int val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeLong(int offset, long val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeFloat(int offset, float val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeDouble(int offset, double val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeWord(int offset, WordBase val, LocationIdentity locationIdentity);
+
+    /**
+     * Initializes the memory at address {@code (this + offset)}. Both the base address and offset
+     * are in bytes. The memory must be uninitialized or zero prior to this operation.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void initializeLong(int offset, long val, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param locationIdentity the identity of the write
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeObject(int offset, Object val, LocationIdentity locationIdentity);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    byte readByte(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    char readChar(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    short readShort(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    int readInt(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    long readLong(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    float readFloat(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    double readDouble(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T readWord(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    Object readObject(WordBase offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    byte readByte(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    char readChar(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    short readShort(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    int readInt(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    long readLong(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    float readFloat(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    double readDouble(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T readWord(int offset);
+
+    /**
+     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @return the result of the memory access
+     *
+     * @since 1.0
+     */
+    Object readObject(int offset);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeByte(WordBase offset, byte val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeChar(WordBase offset, char val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeShort(WordBase offset, short val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeInt(WordBase offset, int val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeLong(WordBase offset, long val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeFloat(WordBase offset, float val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeDouble(WordBase offset, double val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeWord(WordBase offset, WordBase val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeObject(WordBase offset, Object val);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     * <p>
+     * The offset is always treated as a {@link SignedWord} value. However, the static type is
+     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
+     * knows that the highest-order bit of the unsigned value is never used).
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeByte(int offset, byte val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeChar(int offset, char val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeShort(int offset, short val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeInt(int offset, int val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeLong(int offset, long val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeFloat(int offset, float val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeDouble(int offset, double val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeWord(int offset, WordBase val);
+
+    /**
+     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
+     * bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param val the value to be written to memory
+     *
+     * @since 1.0
+     */
+    void writeObject(int offset, Object val);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return The value after the atomic exchange
+     *
+     * @since 1.0
+     */
+    Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
+
+    /**
+     * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
+     * offset are in bytes.
+     *
+     * @param offset the signed offset for the memory access
+     * @param expectedValue the expected value of the atomic exchange
+     * @param newValue the new value of the atomic exchange
+     * @param locationIdentity the identity of the memory location
+     * @return {@code true} if successful. False return indicates that the actual value was not
+     *         equal to the expected value.
+     *
+     * @since 1.0
+     */
+    boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
+
+    // Math functions that are defined in Unsigned, but known to preserve the
+    // pointer-characteristics.
+    // It is therefore safe that they return a static type of Pointer instead of Unsigned.
+
+    /**
+     * Returns a Pointer whose value is {@code (this + val)}.
+     *
+     * @param val value to be added to this Pointer.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer add(UnsignedWord val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this + val)}.
+     *
+     * @param val value to be added to this Pointer.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer add(int val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this - val)}.
+     *
+     * @param val value to be subtracted from this Pointer.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer subtract(UnsignedWord val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this - val)}.
+     *
+     * @param val value to be subtracted from this Pointer.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer subtract(int val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this & val)}.
+     *
+     * @param val value to be AND'ed with this Pointer.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer and(UnsignedWord val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this & val)}.
+     *
+     * @param val value to be AND'ed with this Pointer.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer and(int val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this | val)}.
+     *
+     * @param val value to be OR'ed with this Pointer.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer or(UnsignedWord val);
+
+    /**
+     * Returns a Pointer whose value is {@code (this | val)}.
+     *
+     * @param val value to be OR'ed with this Pointer.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    @Override
+    Pointer or(int val);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 jdk.internal.vm.compiler.word;
+
+/**
+ * Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not
+ * necessarily all the memory access methods defined in {@link Pointer}).
+ *
+ * @since 1.0
+ */
+public interface PointerBase extends ComparableWord {
+
+    /**
+     * Returns true if this pointer is the {@link WordFactory#nullPointer null pointer}.
+     *
+     * @since 1.0
+     */
+    boolean isNull();
+
+    /**
+     * Returns true if this pointer is not the {@link WordFactory#nullPointer null pointer}.
+     *
+     * @since 1.0
+     */
+    boolean isNonNull();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,369 @@
+/*
+ * 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 jdk.internal.vm.compiler.word;
+
+/**
+ * Represents a signed word-sized value.
+ *
+ * @since 1.0
+ */
+public interface SignedWord extends ComparableWord {
+
+    /**
+     * Returns a Signed whose value is {@code (this + val)}.
+     *
+     * @param val value to be added to this Signed.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    SignedWord add(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this - val)}.
+     *
+     * @param val value to be subtracted from this Signed.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    SignedWord subtract(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this * val)}.
+     *
+     * @param val value to be multiplied by this Signed.
+     * @return {@code this * val}
+     *
+     * @since 1.0
+     */
+    SignedWord multiply(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this / val)}.
+     *
+     * @param val value by which this Signed is to be divided.
+     * @return {@code this / val}
+     *
+     * @since 1.0
+     */
+    SignedWord signedDivide(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this % val)}.
+     *
+     * @param val value by which this Signed is to be divided, and the remainder computed.
+     * @return {@code this % val}
+     *
+     * @since 1.0
+     */
+    SignedWord signedRemainder(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this << n)}.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this << n}
+     *
+     * @since 1.0
+     */
+    SignedWord shiftLeft(UnsignedWord n);
+
+    /**
+     * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this >> n}
+     *
+     * @since 1.0
+     */
+    SignedWord signedShiftRight(UnsignedWord n);
+
+    /**
+     * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
+     * if and only if this and val are both negative.)
+     *
+     * @param val value to be AND'ed with this Signed.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    SignedWord and(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
+     * if and only if either this or val is negative.)
+     *
+     * @param val value to be OR'ed with this Signed.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    SignedWord or(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
+     * if and only if exactly one of this and val are negative.)
+     *
+     * @param val value to be XOR'ed with this Signed.
+     * @return {@code this ^ val}
+     *
+     * @since 1.0
+     */
+    SignedWord xor(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (~this)}. (This method returns a negative value if and
+     * only if this Signed is non-negative.)
+     *
+     * @return {@code ~this}
+     *
+     * @since 1.0
+     */
+    SignedWord not();
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this == val}
+     *
+     * @since 1.0
+     */
+    boolean equal(SignedWord val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this != val}
+     *
+     * @since 1.0
+     */
+    boolean notEqual(SignedWord val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this < val}
+     *
+     * @since 1.0
+     */
+    boolean lessThan(SignedWord val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this <= val}
+     *
+     * @since 1.0
+     */
+    boolean lessOrEqual(SignedWord val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this > val}
+     *
+     * @since 1.0
+     */
+    boolean greaterThan(SignedWord val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this >= val}
+     *
+     * @since 1.0
+     */
+    boolean greaterOrEqual(SignedWord val);
+
+    /**
+     * Returns a Signed whose value is {@code (this + val)}.
+     *
+     * @param val value to be added to this Signed.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    SignedWord add(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this - val)}.
+     *
+     * @param val value to be subtracted from this Signed.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    SignedWord subtract(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this * val)}.
+     *
+     * @param val value to be multiplied by this Signed.
+     * @return {@code this * val}
+     *
+     * @since 1.0
+     */
+    SignedWord multiply(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this / val)}.
+     *
+     * @param val value by which this Signed is to be divided.
+     * @return {@code this / val}
+     *
+     * @since 1.0
+     */
+    SignedWord signedDivide(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this % val)}.
+     *
+     * @param val value by which this Signed is to be divided, and the remainder computed.
+     * @return {@code this % val}
+     *
+     * @since 1.0
+     */
+    SignedWord signedRemainder(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this << n)}.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this << n}
+     *
+     * @since 1.0
+     */
+    SignedWord shiftLeft(int n);
+
+    /**
+     * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this >> n}
+     *
+     * @since 1.0
+     */
+    SignedWord signedShiftRight(int n);
+
+    /**
+     * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
+     * if and only if this and val are both negative.)
+     *
+     * @param val value to be AND'ed with this Signed.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    SignedWord and(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
+     * if and only if either this or val is negative.)
+     *
+     * @param val value to be OR'ed with this Signed.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    SignedWord or(int val);
+
+    /**
+     * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
+     * if and only if exactly one of this and val are negative.)
+     *
+     * @param val value to be XOR'ed with this Signed.
+     * @return {@code this ^ val}
+     *
+     * @since 1.0
+     */
+    SignedWord xor(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this == val}
+     *
+     * @since 1.0
+     */
+    boolean equal(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this != val}
+     *
+     * @since 1.0
+     */
+    boolean notEqual(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this < val}
+     *
+     * @since 1.0
+     */
+    boolean lessThan(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this <= val}
+     *
+     * @since 1.0
+     */
+    boolean lessOrEqual(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this > val}
+     *
+     * @since 1.0
+     */
+    boolean greaterThan(int val);
+
+    /**
+     * Compares this Signed with the specified value.
+     *
+     * @param val value to which this Signed is to be compared.
+     * @return {@code this >= val}
+     *
+     * @since 1.0
+     */
+    boolean greaterOrEqual(int val);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,410 @@
+/*
+ * 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 jdk.internal.vm.compiler.word;
+
+/**
+ * Represents an unsigned word-sized value.
+ *
+ * @since 1.0
+ */
+public interface UnsignedWord extends ComparableWord {
+
+    /**
+     * Returns a Unsigned whose value is {@code (this + val)}.
+     *
+     * @param val value to be added to this Unsigned.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord add(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this - val)}.
+     *
+     * @param val value to be subtracted from this Unsigned.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord subtract(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this * val)}.
+     *
+     * @param val value to be multiplied by this Unsigned.
+     * @return {@code this * val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord multiply(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this / val)}.
+     *
+     * @param val value by which this Unsigned is to be divided.
+     * @return {@code this / val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedDivide(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this % val)}.
+     *
+     * @param val value by which this Unsigned is to be divided, and the remainder computed.
+     * @return {@code this % val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedRemainder(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this << n)}.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this << n}
+     *
+     * @since 1.0
+     */
+    UnsignedWord shiftLeft(UnsignedWord n);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this >> n}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedShiftRight(UnsignedWord n);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this & val)}.
+     *
+     * @param val value to be AND'ed with this Unsigned.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord and(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this | val)}.
+     *
+     * @param val value to be OR'ed with this Unsigned.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord or(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this ^ val)}.
+     *
+     * @param val value to be XOR'ed with this Unsigned.
+     * @return {@code this ^ val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord xor(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (~this)}.
+     *
+     * @return {@code ~this}
+     *
+     * @since 1.0
+     */
+    UnsignedWord not();
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this == val}
+     *
+     * @since 1.0
+     */
+    boolean equal(UnsignedWord val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this != val}
+     *
+     * @since 1.0
+     */
+    boolean notEqual(UnsignedWord val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this < val}
+     *
+     * @since 1.0
+     */
+    boolean belowThan(UnsignedWord val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this <= val}
+     *
+     * @since 1.0
+     */
+    boolean belowOrEqual(UnsignedWord val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this > val}
+     *
+     * @since 1.0
+     */
+    boolean aboveThan(UnsignedWord val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this >= val}
+     *
+     * @since 1.0
+     */
+    boolean aboveOrEqual(UnsignedWord val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this + val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be added to this Unsigned.
+     * @return {@code this + val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord add(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this - val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be subtracted from this Unsigned.
+     * @return {@code this - val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord subtract(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this * val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be multiplied by this Unsigned.
+     * @return {@code this * val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord multiply(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this / val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value by which this Unsigned is to be divided.
+     * @return {@code this / val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedDivide(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this % val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value by which this Unsigned is to be divided, and the remainder computed.
+     * @return {@code this % val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedRemainder(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this << n)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this << n}
+     *
+     * @since 1.0
+     */
+    UnsignedWord shiftLeft(int n);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param n shift distance, in bits.
+     * @return {@code this >> n}
+     *
+     * @since 1.0
+     */
+    UnsignedWord unsignedShiftRight(int n);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this & val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be AND'ed with this Unsigned.
+     * @return {@code this & val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord and(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this | val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be OR'ed with this Unsigned.
+     * @return {@code this | val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord or(int val);
+
+    /**
+     * Returns a Unsigned whose value is {@code (this ^ val)}.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to be XOR'ed with this Unsigned.
+     * @return {@code this ^ val}
+     *
+     * @since 1.0
+     */
+    UnsignedWord xor(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this == val}
+     *
+     * @since 1.0
+     */
+    boolean equal(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this != val}
+     *
+     * @since 1.0
+     */
+    boolean notEqual(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this < val}
+     *
+     * @since 1.0
+     */
+    boolean belowThan(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this <= val}
+     *
+     * @since 1.0
+     */
+    boolean belowOrEqual(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this > val}
+     *
+     * @since 1.0
+     */
+    boolean aboveThan(int val);
+
+    /**
+     * Compares this Unsigned with the specified value.
+     * <p>
+     * Note that the right operand is a signed value, while the operation is performed unsigned.
+     * Therefore, the result is only well-defined for positive right operands.
+     *
+     * @param val value to which this Unsigned is to be compared.
+     * @return {@code this >= val}
+     *
+     * @since 1.0
+     */
+    boolean aboveOrEqual(int val);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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 jdk.internal.vm.compiler.word;
+
+/**
+ * The root of the interface hierarchy for machine-word-sized values.
+ *
+ * @since 1.0
+ */
+public interface WordBase {
+
+    /**
+     * Conversion to a Java primitive value.
+     *
+     * @since 1.0
+     */
+    long rawValue();
+
+    /**
+     * This is deprecated because of the easy to mistype name collision between {@link #equals} and
+     * the other word based equality routines. In general you should never be statically calling
+     * this method anyway.
+     *
+     * @since 1.0
+     */
+    @Override
+    @Deprecated
+    boolean equals(Object o);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word;
+
+import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
+import jdk.internal.vm.compiler.word.impl.WordFactoryOpcode;
+import jdk.internal.vm.compiler.word.impl.WordFactoryOperation;
+
+/**
+ * Provides factory method to create machine-word-sized values.
+ *
+ * @since 1.0
+ */
+public final class WordFactory {
+
+    private WordFactory() {
+    }
+
+    /**
+     * The constant 0, i.e., the word with no bits set. There is no difference between a signed and
+     * unsigned zero.
+     *
+     * @return the constant 0.
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
+    public static <T extends WordBase> T zero() {
+        return WordBoxFactory.box(0L);
+    }
+
+    /**
+     * The null pointer, i.e., the pointer with no bits set. There is no difference to a signed or
+     * unsigned {@link #zero}.
+     *
+     * @return the null pointer.
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
+    public static <T extends PointerBase> T nullPointer() {
+        return WordBoxFactory.box(0L);
+    }
+
+    /**
+     * Unsafe conversion from a Java long value to a Word. The parameter is treated as an unsigned
+     * 64-bit value (in contrast to the semantics of a Java long).
+     *
+     * @param val a 64 bit unsigned value
+     * @return the value cast to Word
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
+    public static <T extends UnsignedWord> T unsigned(long val) {
+        return WordBoxFactory.box(val);
+    }
+
+    /**
+     * Unsafe conversion from a Java long value to a {@link PointerBase pointer}. The parameter is
+     * treated as an unsigned 64-bit value (in contrast to the semantics of a Java long).
+     *
+     * @param val a 64 bit unsigned value
+     * @return the value cast to PointerBase
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
+    public static <T extends PointerBase> T pointer(long val) {
+        return WordBoxFactory.box(val);
+    }
+
+    /**
+     * Unsafe conversion from a Java int value to a Word. The parameter is treated as an unsigned
+     * 32-bit value (in contrast to the semantics of a Java int).
+     *
+     * @param val a 32 bit unsigned value
+     * @return the value cast to Word
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
+    public static <T extends UnsignedWord> T unsigned(int val) {
+        return WordBoxFactory.box(val & 0xffffffffL);
+    }
+
+    /**
+     * Unsafe conversion from a Java long value to a Word. The parameter is treated as a signed
+     * 64-bit value (unchanged semantics of a Java long).
+     *
+     * @param val a 64 bit signed value
+     * @return the value cast to Word
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
+    public static <T extends SignedWord> T signed(long val) {
+        return WordBoxFactory.box(val);
+    }
+
+    /**
+     * Unsafe conversion from a Java int value to a Word. The parameter is treated as a signed
+     * 32-bit value (unchanged semantics of a Java int).
+     *
+     * @param val a 32 bit signed value
+     * @return the value cast to Word
+     *
+     * @since 1.0
+     */
+    @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
+    public static <T extends SignedWord> T signed(int val) {
+        return WordBoxFactory.box(val);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordBoxFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word.impl;
+
+import jdk.internal.vm.compiler.word.WordBase;
+
+/**
+ * Base class for a factory to create boxed {@link Word} instances. A concrete subclass must
+ * initialize {@link #boxFactory}.
+ */
+public abstract class WordBoxFactory {
+
+    protected static WordBoxFactory boxFactory;
+
+    protected abstract <T extends WordBase> T boxImpl(long val);
+
+    public static <T extends WordBase> T box(long val) {
+        return boxFactory.boxImpl(val);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOpcode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word.impl;
+
+/**
+ * The canonical {@link WordFactoryOperation} represented by a method in a word type.
+ */
+public enum WordFactoryOpcode {
+    ZERO,
+    FROM_UNSIGNED,
+    FROM_SIGNED,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOperation.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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 jdk.internal.vm.compiler.word.impl;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Links a method to a canonical operation represented by an {@link WordFactoryOpcode} val.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface WordFactoryOperation {
+    WordFactoryOpcode opcode();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+/*
+ @ApiInfo(
+ group="Graal SDK"
+ )
+ */
+/**
+ * This package provides a low-level mechanism to use machine-word-sized values in Java. The package
+ * can only be used in the context of native images or Graal snippets.
+ *
+ * @since 1.0
+ */
+package jdk.internal.vm.compiler.word;
\ No newline at end of file
--- a/src/jdk.internal.vm.compiler/share/classes/module-info.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/module-info.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,9 +36,10 @@
     uses org.graalvm.compiler.hotspot.CompilerConfigurationFactory;
     uses org.graalvm.compiler.hotspot.HotSpotBackendFactory;
     uses org.graalvm.compiler.hotspot.HotSpotCodeCacheListener;
-    uses org.graalvm.compiler.options.OptionValuesAccess;
+    uses org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
     uses org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
 
+    exports jdk.internal.vm.compiler.collections        to jdk.internal.vm.compiler.management;
     exports org.graalvm.compiler.api.directives         to jdk.aot;
     exports org.graalvm.compiler.api.runtime            to jdk.aot;
     exports org.graalvm.compiler.api.replacements       to jdk.aot;
@@ -46,9 +47,13 @@
     exports org.graalvm.compiler.bytecode               to jdk.aot;
     exports org.graalvm.compiler.code                   to jdk.aot;
     exports org.graalvm.compiler.core                   to jdk.aot;
-    exports org.graalvm.compiler.core.common            to jdk.aot;
+    exports org.graalvm.compiler.core.common            to
+        jdk.aot,
+        jdk.internal.vm.compiler.management;
     exports org.graalvm.compiler.core.target            to jdk.aot;
-    exports org.graalvm.compiler.debug                  to jdk.aot;
+    exports org.graalvm.compiler.debug                  to
+        jdk.aot,
+        jdk.internal.vm.compiler.management;
     exports org.graalvm.compiler.graph                  to jdk.aot;
     exports org.graalvm.compiler.hotspot                to
         jdk.aot,
@@ -62,12 +67,17 @@
     exports org.graalvm.compiler.lir.phases             to jdk.aot;
     exports org.graalvm.compiler.nodes                  to jdk.aot;
     exports org.graalvm.compiler.nodes.graphbuilderconf to jdk.aot;
-    exports org.graalvm.compiler.options                to jdk.aot;
+    exports org.graalvm.compiler.options                to
+        jdk.aot,
+        jdk.internal.vm.compiler.management;
     exports org.graalvm.compiler.phases                 to jdk.aot;
     exports org.graalvm.compiler.phases.tiers           to jdk.aot;
     exports org.graalvm.compiler.printer                to jdk.aot;
     exports org.graalvm.compiler.runtime                to jdk.aot;
     exports org.graalvm.compiler.replacements           to jdk.aot;
+    exports org.graalvm.compiler.serviceprovider        to
+        jdk.aot,
+        jdk.internal.vm.compiler.management;
     exports org.graalvm.compiler.word                   to jdk.aot;
-    exports org.graalvm.word                            to jdk.aot;
+    exports jdk.internal.vm.compiler.word               to jdk.aot;
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapImplTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicSet;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class EconomicMapImplTest {
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testRemoveNull() {
-        EconomicMap<Integer, Integer> map = EconomicMap.create(10);
-        map.removeKey(null);
-    }
-
-    @Test
-    public void testInitFromHashSet() {
-        UnmodifiableEconomicSet<Integer> set = new UnmodifiableEconomicSet<Integer>() {
-
-            @Override
-            public boolean contains(Integer element) {
-                return element == 0;
-            }
-
-            @Override
-            public int size() {
-                return 1;
-            }
-
-            @Override
-            public boolean isEmpty() {
-                return false;
-            }
-
-            @Override
-            public Iterator<Integer> iterator() {
-                return new Iterator<Integer>() {
-
-                    private boolean visited = false;
-
-                    @Override
-                    public boolean hasNext() {
-                        return !visited;
-                    }
-
-                    @Override
-                    public Integer next() {
-                        if (visited) {
-                            return null;
-                        } else {
-                            visited = true;
-                            return 1;
-                        }
-                    }
-                };
-            }
-        };
-
-        EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.DEFAULT, set);
-        Assert.assertEquals(newSet.size(), 1);
-    }
-
-    @Test
-    public void testCopyHash() {
-        EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
-        set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
-        EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.IDENTITY, set);
-        Assert.assertEquals(newSet.size(), 10);
-        newSet.remove(8);
-        newSet.remove(9);
-        Assert.assertEquals(newSet.size(), 8);
-    }
-
-    @Test
-    public void testNewEquivalence() {
-        EconomicSet<Integer> set = EconomicSet.create(new Equivalence() {
-            @Override
-            public boolean equals(Object a, Object b) {
-                return false;
-            }
-
-            @Override
-            public int hashCode(Object o) {
-                return 0;
-            }
-        });
-        set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
-        Assert.assertTrue(set.add(new Integer(0)));
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testMapPutNull() {
-        EconomicMap<Integer, Integer> map = EconomicMap.create();
-        map.put(null, null);
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapLargeTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Objects;
-import java.util.Random;
-
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.UnmodifiableMapCursor;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class EconomicMapLargeTest {
-
-    @Parameter(value = 0) public EconomicMap<Object, Object> testMap;
-    @Parameter(value = 1) public EconomicMap<Object, Object> referenceMap;
-    @Parameter(value = 2) public String name;
-
-    @Parameters(name = "{2}")
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.create(Equivalence.DEFAULT), "EconomicMap"},
-                        new Object[]{EconomicMap.create(Equivalence.IDENTITY), EconomicMap.create(Equivalence.IDENTITY), "EconomicMap(IDENTITY)"},
-                        new Object[]{EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE), EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE),
-                                        "EconomicMap(IDENTITY_WITH_SYSTEM_HASHCODE)"},
-                        new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.wrapMap(new LinkedHashMap<>()), "EconomicMap<->wrapMap"},
-                        new Object[]{EconomicMap.wrapMap(new LinkedHashMap<>()), EconomicMap.wrapMap(new LinkedHashMap<>()), "wrapMap"});
-    }
-
-    private static int[] createRandomRange(Random random, int count) {
-        int[] result = new int[count];
-        for (int i = 0; i < count; ++i) {
-            int range = random.nextInt(14);
-            if (range == 0 || range > 10) {
-                range = Integer.MAX_VALUE;
-            } else if (range == 10) {
-                range = 100;
-            }
-            result[i] = range;
-        }
-        return result;
-    }
-
-    private static final class BadHashClass {
-        private int value;
-
-        BadHashClass(int randomInt) {
-            this.value = randomInt;
-        }
-
-        @Override
-        public int hashCode() {
-            return 0;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof BadHashClass) {
-                BadHashClass badHashClass = (BadHashClass) other;
-                return badHashClass.value == value;
-            }
-            return false;
-        }
-    }
-
-    interface MapAction {
-        Object perform(EconomicMap<Object, Object> map, int randomInt);
-    }
-
-    static final Object EXISTING_VALUE = new Object();
-
-    static final MapAction[] INCREASE_ACTIONS = new MapAction[]{
-                    (map, randomInt) -> map.put(randomInt, "value"),
-                    (map, randomInt) -> map.get(randomInt)
-    };
-
-    static final MapAction[] ACTIONS = new MapAction[]{
-                    (map, randomInt) -> map.removeKey(randomInt),
-                    (map, randomInt) -> map.put(randomInt, "value"),
-                    (map, randomInt) -> map.put(randomInt, null),
-                    (map, randomInt) -> map.put(EXISTING_VALUE, randomInt),
-                    (map, randomInt) -> {
-                        if (randomInt == 0) {
-                            map.clear();
-                        }
-                        return map.isEmpty();
-                    },
-                    (map, randomInt) -> map.containsKey(randomInt),
-                    (map, randomInt) -> map.get(randomInt),
-                    (map, randomInt) -> map.put(new BadHashClass(randomInt), "unique"),
-                    (map, randomInt) -> {
-                        if (randomInt == 0) {
-                            map.replaceAll((key, value) -> Objects.toString(value) + "!");
-                        }
-                        return map.isEmpty();
-                    }
-
-    };
-
-    @Test
-    public void testVeryLarge() {
-        testMap.clear();
-        referenceMap.clear();
-
-        Random random = new Random(0);
-        for (int i = 0; i < 200000; ++i) {
-            for (int j = 0; j < INCREASE_ACTIONS.length; ++j) {
-                int nextInt = random.nextInt(10000000);
-                MapAction action = INCREASE_ACTIONS[j];
-                Object result = action.perform(testMap, nextInt);
-                Object referenceResult = action.perform(referenceMap, nextInt);
-                Assert.assertEquals(result, referenceResult);
-            }
-        }
-    }
-
-    /**
-     * Tests a sequence of random operations on the map.
-     */
-    @Test
-    public void testAddRemove() {
-        testMap.clear();
-        referenceMap.clear();
-
-        for (int seed = 0; seed < 10; ++seed) {
-            Random random = new Random(seed);
-            int[] ranges = createRandomRange(random, ACTIONS.length);
-            int value = random.nextInt(10000);
-            for (int i = 0; i < value; ++i) {
-                for (int j = 0; j < ACTIONS.length; ++j) {
-                    if (random.nextInt(ranges[j]) == 0) {
-                        int nextInt = random.nextInt(100);
-                        MapAction action = ACTIONS[j];
-                        Object result = action.perform(testMap, nextInt);
-                        Object referenceResult = action.perform(referenceMap, nextInt);
-                        Assert.assertEquals(result, referenceResult);
-                        if (j % 100 == 0) {
-                            checkEquality(testMap, referenceMap);
-                        }
-                    }
-                }
-
-                if (random.nextInt(20) == 0) {
-                    removeElement(random.nextInt(100), testMap, referenceMap);
-                }
-            }
-        }
-    }
-
-    private static void removeElement(int index, EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
-        Assert.assertEquals(referenceMap.size(), map.size());
-        MapCursor<?, ?> cursor = map.getEntries();
-        MapCursor<?, ?> referenceCursor = referenceMap.getEntries();
-        int z = 0;
-        while (cursor.advance()) {
-            Assert.assertTrue(referenceCursor.advance());
-            Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
-            Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
-            if (index == z) {
-                cursor.remove();
-                referenceCursor.remove();
-            }
-            ++z;
-        }
-
-        Assert.assertFalse(referenceCursor.advance());
-    }
-
-    private static void checkEquality(EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
-        Assert.assertEquals(referenceMap.size(), map.size());
-
-        // Check entries.
-        UnmodifiableMapCursor<?, ?> cursor = map.getEntries();
-        UnmodifiableMapCursor<?, ?> referenceCursor = referenceMap.getEntries();
-        while (cursor.advance()) {
-            Assert.assertTrue(referenceCursor.advance());
-            Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
-            Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
-        }
-
-        // Check keys.
-        Iterator<?> iterator = map.getKeys().iterator();
-        Iterator<?> referenceIterator = referenceMap.getKeys().iterator();
-        while (iterator.hasNext()) {
-            Assert.assertTrue(referenceIterator.hasNext());
-            Assert.assertEquals(iterator.next(), referenceIterator.next());
-        }
-
-        // Check values.
-        iterator = map.getValues().iterator();
-        referenceIterator = referenceMap.getValues().iterator();
-        while (iterator.hasNext()) {
-            Assert.assertTrue(referenceIterator.hasNext());
-            Assert.assertEquals(iterator.next(), referenceIterator.next());
-        }
-        Assert.assertFalse(referenceIterator.hasNext());
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import java.util.LinkedHashMap;
-
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class EconomicMapTest {
-
-    @Test
-    public void testMapGetDefault() {
-        EconomicMap<Integer, Integer> map = EconomicMap.create();
-        map.put(0, 1);
-        Assert.assertEquals(map.get(0, 2), Integer.valueOf(1));
-        Assert.assertEquals(map.get(1, 2), Integer.valueOf(2));
-    }
-
-    @Test
-    public void testMapPutAll() {
-        EconomicMap<Integer, Integer> map = EconomicMap.create();
-        EconomicMap<Integer, Integer> newMap = EconomicMap.wrapMap(new LinkedHashMap<>());
-        newMap.put(1, 1);
-        newMap.put(2, 4);
-        map.putAll(newMap);
-        Assert.assertEquals(map.size(), 2);
-
-        UnmodifiableEconomicMap<Integer, Integer> unmodifiableEconomicMap = EconomicMap.create(newMap);
-
-        map.removeKey(1);
-        map.put(2, 2);
-        map.put(3, 9);
-
-        map.putAll(unmodifiableEconomicMap);
-        Assert.assertEquals(map.size(), 3);
-        Assert.assertEquals(map.get(2), Integer.valueOf(4));
-    }
-
-    @Test
-    public void testToString() {
-        EconomicMap<Integer, Integer> map = EconomicMap.create();
-        map.put(0, 0);
-        map.put(1, 1);
-        Assert.assertEquals(map.toString(), "map(size=2, {(0,0),(1,1)})");
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicSetTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class EconomicSetTest {
-
-    @Test
-    public void testUtilities() {
-        EconomicSet<Integer> set = EconomicSet.create(0);
-        set.add(0);
-        Assert.assertTrue(set.add(1));
-        Assert.assertEquals(set.size(), 2);
-        Assert.assertFalse(set.add(1));
-        Assert.assertEquals(set.size(), 2);
-        set.remove(1);
-        Assert.assertEquals(set.size(), 1);
-        set.remove(2);
-        Assert.assertEquals(set.size(), 1);
-        Assert.assertTrue(set.add(1));
-        set.clear();
-        Assert.assertEquals(set.size(), 0);
-    }
-
-    @Test
-    public void testAddAll() {
-        EconomicSet<Integer> set = EconomicSet.create();
-        set.addAll(Arrays.asList(0, 1, 0));
-        Assert.assertEquals(set.size(), 2);
-
-        EconomicSet<Integer> newSet = EconomicSet.create();
-        newSet.addAll(Arrays.asList(1, 2));
-        Assert.assertEquals(newSet.size(), 2);
-        newSet.addAll(set);
-        Assert.assertEquals(newSet.size(), 3);
-    }
-
-    @Test
-    public void testRemoveAll() {
-        EconomicSet<Integer> set = EconomicSet.create();
-        set.addAll(Arrays.asList(0, 1));
-
-        set.removeAll(Arrays.asList(1, 2));
-        Assert.assertEquals(set.size(), 1);
-
-        set.removeAll(EconomicSet.create(set));
-        Assert.assertEquals(set.size(), 0);
-    }
-
-    @Test
-    public void testRetainAll() {
-        EconomicSet<Integer> set = EconomicSet.create();
-        set.addAll(Arrays.asList(0, 1, 2));
-
-        EconomicSet<Integer> newSet = EconomicSet.create();
-        newSet.addAll(Arrays.asList(2, 3));
-
-        set.retainAll(newSet);
-        Assert.assertEquals(set.size(), 1);
-    }
-
-    @Test
-    public void testToArray() {
-        EconomicSet<Integer> set = EconomicSet.create();
-        set.addAll(Arrays.asList(0, 1));
-        Assert.assertArrayEquals(set.toArray(new Integer[2]), new Integer[]{0, 1});
-    }
-
-    @Test
-    public void testToString() {
-        EconomicSet<Integer> set = EconomicSet.create();
-        set.addAll(Arrays.asList(0, 1));
-        Assert.assertEquals(set.toString(), "set(size=2, {0,1})");
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testToUnalignedArray() {
-        Assert.assertArrayEquals(EconomicSet.create().toArray(new Integer[2]), new Integer[0]);
-    }
-
-    @Test
-    public void testSetRemoval() {
-        ArrayList<Integer> initialList = new ArrayList<>();
-        ArrayList<Integer> removalList = new ArrayList<>();
-        ArrayList<Integer> finalList = new ArrayList<>();
-        EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
-        set.add(1);
-        set.add(2);
-        set.add(3);
-        set.add(4);
-        set.add(5);
-        set.add(6);
-        set.add(7);
-        set.add(8);
-        set.add(9);
-        Iterator<Integer> i1 = set.iterator();
-        while (i1.hasNext()) {
-            initialList.add(i1.next());
-        }
-        int size = 0;
-        Iterator<Integer> i2 = set.iterator();
-        while (i2.hasNext()) {
-            Integer elem = i2.next();
-            if (size++ < 8) {
-                i2.remove();
-            }
-            removalList.add(elem);
-        }
-        Iterator<Integer> i3 = set.iterator();
-        while (i3.hasNext()) {
-            finalList.add(i3.next());
-        }
-        Assert.assertEquals(initialList, removalList);
-        Assert.assertEquals(1, finalList.size());
-        Assert.assertEquals(new Integer(9), finalList.get(0));
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EquivalenceTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import org.graalvm.collections.Equivalence;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class EquivalenceTest {
-
-    private static final String TEST_STRING = "Graal";
-    private static final String TEST_STRING2 = "Graal2";
-
-    @Test
-    public void testDEFAULT() {
-        Assert.assertTrue(Equivalence.DEFAULT.equals(TEST_STRING, new String(TEST_STRING)));
-        Assert.assertEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(new String(TEST_STRING)));
-        Assert.assertFalse(Equivalence.DEFAULT.equals(TEST_STRING, TEST_STRING2));
-        Assert.assertNotEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(TEST_STRING2));
-    }
-
-    @Test
-    public void testIDENTITY() {
-        Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, new String(TEST_STRING)));
-        Assert.assertEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(new String(TEST_STRING)));
-        Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, TEST_STRING2));
-        Assert.assertNotEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(TEST_STRING2));
-    }
-
-    @Test
-    public void testIDENTITYWITHSYSTEMHASHCODE() {
-        Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, new String(TEST_STRING)));
-        Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(new String(TEST_STRING)));
-        Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, TEST_STRING2));
-        Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING2));
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/PairTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections.test;
-
-import org.graalvm.collections.Pair;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PairTest {
-
-    @Test
-    public void testCreate() {
-        Assert.assertEquals(Pair.create(null, null), Pair.empty());
-        Assert.assertNotEquals(Pair.create(null, null), null);
-        Assert.assertEquals(Pair.createLeft(null), Pair.empty());
-        Assert.assertEquals(Pair.createRight(null), Pair.empty());
-        Assert.assertEquals(Pair.create(1, null), Pair.createLeft(1));
-        Assert.assertEquals(Pair.create(null, 1), Pair.createRight(1));
-    }
-
-    @Test
-    public void testUtilities() {
-        Pair<Integer, Integer> pair = Pair.create(1, null);
-        Assert.assertEquals(pair.getLeft(), Integer.valueOf(1));
-        Assert.assertEquals(pair.getRight(), null);
-        Assert.assertEquals(pair.toString(), "(1, null)");
-        Assert.assertEquals(pair.hashCode(), Pair.createLeft(1).hashCode());
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMap.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.function.BiFunction;
-
-/**
- * Memory efficient map data structure.
- *
- * @since 1.0
- */
-public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
-
-    /**
-     * Associates {@code value} with {@code key} in this map. If the map previously contained a
-     * mapping for {@code key}, the old value is replaced by {@code value}.
-     *
-     * @return the previous value associated with {@code key}, or {@code null} if there was no
-     *         mapping for {@code key}.
-     * @since 1.0
-     */
-    V put(K key, V value);
-
-    /**
-     * Copies all of the mappings from {@code other} to this map.
-     *
-     * @since 1.0
-     */
-    default void putAll(EconomicMap<K, V> other) {
-        MapCursor<K, V> e = other.getEntries();
-        while (e.advance()) {
-            put(e.getKey(), e.getValue());
-        }
-    }
-
-    /**
-     * Copies all of the mappings from {@code other} to this map.
-     *
-     * @since 1.0
-     */
-    default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
-        UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
-        while (entry.advance()) {
-            put(entry.getKey(), entry.getValue());
-        }
-    }
-
-    /**
-     * Removes all of the mappings from this map. The map will be empty after this call returns.
-     *
-     * @since 1.0
-     */
-    void clear();
-
-    /**
-     * Removes the mapping for {@code key} from this map if it is present. The map will not contain
-     * a mapping for {@code key} once the call returns.
-     *
-     * @return the previous value associated with {@code key}, or {@code null} if there was no
-     *         mapping for {@code key}.
-     * @since 1.0
-     */
-    V removeKey(K key);
-
-    /**
-     * Returns a {@link MapCursor} view of the mappings contained in this map.
-     *
-     * @since 1.0
-     */
-    @Override
-    MapCursor<K, V> getEntries();
-
-    /**
-     * Replaces each entry's value with the result of invoking {@code function} on that entry until
-     * all entries have been processed or the function throws an exception. Exceptions thrown by the
-     * function are relayed to the caller.
-     *
-     * @since 1.0
-     */
-    void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set with the default
-     * {@link Equivalence#DEFAULT} comparison strategy for keys.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create() {
-        return EconomicMap.create(Equivalence.DEFAULT);
-    }
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set with the default
-     * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
-     * capacity.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create(int initialCapacity) {
-        return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
-    }
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set with the given comparison
-     * strategy for keys.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
-        return EconomicMapImpl.create(strategy, false);
-    }
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set with the default
-     * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
-     * specified existing map.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
-        return EconomicMap.create(Equivalence.DEFAULT, m);
-    }
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set and copies all elements from
-     * the specified existing map.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
-        return EconomicMapImpl.create(strategy, m, false);
-    }
-
-    /**
-     * Creates a new map that guarantees insertion order on the key set and initializes with a
-     * specified capacity.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
-        return EconomicMapImpl.create(strategy, initialCapacity, false);
-    }
-
-    /**
-     * Wraps an existing {@link Map} as an {@link EconomicMap}.
-     *
-     * @since 1.0
-     */
-    static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
-        return new EconomicMap<K, V>() {
-
-            @Override
-            public V get(K key) {
-                V result = map.get(key);
-                return result;
-            }
-
-            @Override
-            public V put(K key, V value) {
-                V result = map.put(key, value);
-                return result;
-            }
-
-            @Override
-            public int size() {
-                int result = map.size();
-                return result;
-            }
-
-            @Override
-            public boolean containsKey(K key) {
-                return map.containsKey(key);
-            }
-
-            @Override
-            public void clear() {
-                map.clear();
-            }
-
-            @Override
-            public V removeKey(K key) {
-                V result = map.remove(key);
-                return result;
-            }
-
-            @Override
-            public Iterable<V> getValues() {
-                return map.values();
-            }
-
-            @Override
-            public Iterable<K> getKeys() {
-                return map.keySet();
-            }
-
-            @Override
-            public boolean isEmpty() {
-                return map.isEmpty();
-            }
-
-            @Override
-            public MapCursor<K, V> getEntries() {
-                Iterator<java.util.Map.Entry<K, V>> iterator = map.entrySet().iterator();
-                return new MapCursor<K, V>() {
-
-                    private Map.Entry<K, V> current;
-
-                    @Override
-                    public boolean advance() {
-                        boolean result = iterator.hasNext();
-                        if (result) {
-                            current = iterator.next();
-                        }
-
-                        return result;
-                    }
-
-                    @Override
-                    public K getKey() {
-                        return current.getKey();
-                    }
-
-                    @Override
-                    public V getValue() {
-                        return current.getValue();
-                    }
-
-                    @Override
-                    public void remove() {
-                        iterator.remove();
-                    }
-                };
-            }
-
-            @Override
-            public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
-                map.replaceAll(function);
-            }
-        };
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMapImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,857 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-import java.util.Iterator;
-import java.util.Objects;
-import java.util.function.BiFunction;
-
-/**
- * Implementation of a map with a memory-efficient structure that always preserves insertion order
- * when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal
- * {@link #INITIAL_CAPACITY} or smaller 256.
- *
- * The key/value pairs are kept in an expanding flat object array with keys at even indices and
- * values at odd indices. If the map has smaller or equal to {@link #HASH_THRESHOLD} entries, there
- * is no additional hash data structure and comparisons are done via linear checking of the
- * key/value pairs. For the case where the equality check is particularly cheap (e.g., just an
- * object identity comparison), this limit below which the map is without an actual hash table is
- * higher and configured at {@link #HASH_THRESHOLD_IDENTITY_COMPARE}.
- *
- * When the hash table needs to be constructed, the field {@link #hashArray} becomes a new hash
- * array where an entry of 0 means no hit and otherwise denotes the entry number in the
- * {@link #entries} array. The hash array is interpreted as an actual byte array if the indices fit
- * within 8 bit, or as an array of short values if the indices fit within 16 bit, or as an array of
- * integer values in other cases.
- *
- * Hash collisions are handled by chaining a linked list of {@link CollisionLink} objects that take
- * the place of the values in the {@link #entries} array.
- *
- * Removing entries will put {@code null} into the {@link #entries} array. If the occupation of the
- * map falls below a specific threshold, the map will be compressed via the
- * {@link #maybeCompress(int)} method.
- */
-final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> {
-
-    /**
-     * Initial number of key/value pair entries that is allocated in the first entries array.
-     */
-    private static final int INITIAL_CAPACITY = 4;
-
-    /**
-     * Maximum number of entries that are moved linearly forward if a key is removed.
-     */
-    private static final int COMPRESS_IMMEDIATE_CAPACITY = 8;
-
-    /**
-     * Minimum number of key/value pair entries added when the entries array is increased in size.
-     */
-    private static final int MIN_CAPACITY_INCREASE = 8;
-
-    /**
-     * Number of entries above which a hash table is created.
-     */
-    private static final int HASH_THRESHOLD = 4;
-
-    /**
-     * Number of entries above which a hash table is created when equality can be checked with
-     * object identity.
-     */
-    private static final int HASH_THRESHOLD_IDENTITY_COMPARE = 8;
-
-    /**
-     * Maximum number of entries allowed in the map.
-     */
-    private static final int MAX_ELEMENT_COUNT = Integer.MAX_VALUE >> 1;
-
-    /**
-     * Number of entries above which more than 1 byte is necessary for the hash index.
-     */
-    private static final int LARGE_HASH_THRESHOLD = ((1 << Byte.SIZE) << 1);
-
-    /**
-     * Number of entries above which more than 2 bytes are are necessary for the hash index.
-     */
-    private static final int VERY_LARGE_HASH_THRESHOLD = (LARGE_HASH_THRESHOLD << Byte.SIZE);
-
-    /**
-     * Total number of entries (actual entries plus deleted entries).
-     */
-    private int totalEntries;
-
-    /**
-     * Number of deleted entries.
-     */
-    private int deletedEntries;
-
-    /**
-     * Entries array with even indices storing keys and odd indices storing values.
-     */
-    private Object[] entries;
-
-    /**
-     * Hash array that is interpreted either as byte or short or int array depending on number of
-     * map entries.
-     */
-    private byte[] hashArray;
-
-    /**
-     * The strategy used for comparing keys or {@code null} for denoting special strategy
-     * {@link Equivalence#IDENTITY}.
-     */
-    private final Equivalence strategy;
-
-    /**
-     * Intercept method for debugging purposes.
-     */
-    private static <K, V> EconomicMapImpl<K, V> intercept(EconomicMapImpl<K, V> map) {
-        return map;
-    }
-
-    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, boolean isSet) {
-        return intercept(new EconomicMapImpl<>(strategy, isSet));
-    }
-
-    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity, boolean isSet) {
-        return intercept(new EconomicMapImpl<>(strategy, initialCapacity, isSet));
-    }
-
-    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
-        return intercept(new EconomicMapImpl<>(strategy, other, isSet));
-    }
-
-    public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
-        return intercept(new EconomicMapImpl<>(strategy, other, isSet));
-    }
-
-    private EconomicMapImpl(Equivalence strategy, boolean isSet) {
-        if (strategy == Equivalence.IDENTITY) {
-            this.strategy = null;
-        } else {
-            this.strategy = strategy;
-        }
-        this.isSet = isSet;
-    }
-
-    private EconomicMapImpl(Equivalence strategy, int initialCapacity, boolean isSet) {
-        this(strategy, isSet);
-        init(initialCapacity);
-    }
-
-    private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
-        this(strategy, isSet);
-        if (!initFrom(other)) {
-            init(other.size());
-            putAll(other);
-        }
-    }
-
-    private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
-        this(strategy, isSet);
-        if (!initFrom(other)) {
-            init(other.size());
-            addAll(other);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private boolean initFrom(Object o) {
-        if (o instanceof EconomicMapImpl) {
-            EconomicMapImpl<K, V> otherMap = (EconomicMapImpl<K, V>) o;
-            // We are only allowed to directly copy if the strategies of the two maps are the same.
-            if (strategy == otherMap.strategy) {
-                totalEntries = otherMap.totalEntries;
-                deletedEntries = otherMap.deletedEntries;
-                if (otherMap.entries != null) {
-                    entries = otherMap.entries.clone();
-                }
-                if (otherMap.hashArray != null) {
-                    hashArray = otherMap.hashArray.clone();
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void init(int size) {
-        if (size > INITIAL_CAPACITY) {
-            entries = new Object[size << 1];
-        }
-    }
-
-    /**
-     * Links the collisions. Needs to be immutable class for allowing efficient shallow copy from
-     * other map on construction.
-     */
-    private static final class CollisionLink {
-
-        CollisionLink(Object value, int next) {
-            this.value = value;
-            this.next = next;
-        }
-
-        final Object value;
-
-        /**
-         * Index plus one of the next entry in the collision link chain.
-         */
-        final int next;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public V get(K key) {
-        Objects.requireNonNull(key);
-
-        int index = find(key);
-        if (index != -1) {
-            return (V) getValue(index);
-        }
-        return null;
-    }
-
-    private int find(K key) {
-        if (hasHashArray()) {
-            return findHash(key);
-        } else {
-            return findLinear(key);
-        }
-    }
-
-    private int findLinear(K key) {
-        for (int i = 0; i < totalEntries; i++) {
-            Object entryKey = entries[i << 1];
-            if (entryKey != null && compareKeys(key, entryKey)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private boolean compareKeys(Object key, Object entryKey) {
-        if (key == entryKey) {
-            return true;
-        }
-        if (strategy != null && strategy != Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
-            if (strategy == Equivalence.DEFAULT) {
-                return key.equals(entryKey);
-            } else {
-                return strategy.equals(key, entryKey);
-            }
-        }
-        return false;
-    }
-
-    private int findHash(K key) {
-        int index = getHashArray(getHashIndex(key)) - 1;
-        if (index != -1) {
-            Object entryKey = getKey(index);
-            if (compareKeys(key, entryKey)) {
-                return index;
-            } else {
-                Object entryValue = getRawValue(index);
-                if (entryValue instanceof CollisionLink) {
-                    return findWithCollision(key, (CollisionLink) entryValue);
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    private int findWithCollision(K key, CollisionLink initialEntryValue) {
-        int index;
-        Object entryKey;
-        CollisionLink entryValue = initialEntryValue;
-        while (true) {
-            CollisionLink collisionLink = entryValue;
-            index = collisionLink.next;
-            entryKey = getKey(index);
-            if (compareKeys(key, entryKey)) {
-                return index;
-            } else {
-                Object value = getRawValue(index);
-                if (value instanceof CollisionLink) {
-                    entryValue = (CollisionLink) getRawValue(index);
-                } else {
-                    return -1;
-                }
-            }
-        }
-    }
-
-    private int getHashArray(int index) {
-        if (entries.length < LARGE_HASH_THRESHOLD) {
-            return (hashArray[index] & 0xFF);
-        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
-            int adjustedIndex = index << 1;
-            return (hashArray[adjustedIndex] & 0xFF) | ((hashArray[adjustedIndex + 1] & 0xFF) << 8);
-        } else {
-            int adjustedIndex = index << 2;
-            return (hashArray[adjustedIndex] & 0xFF) | ((hashArray[adjustedIndex + 1] & 0xFF) << 8) | ((hashArray[adjustedIndex + 2] & 0xFF) << 16) | ((hashArray[adjustedIndex + 3] & 0xFF) << 24);
-        }
-    }
-
-    private void setHashArray(int index, int value) {
-        if (entries.length < LARGE_HASH_THRESHOLD) {
-            hashArray[index] = (byte) value;
-        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
-            int adjustedIndex = index << 1;
-            hashArray[adjustedIndex] = (byte) value;
-            hashArray[adjustedIndex + 1] = (byte) (value >> 8);
-        } else {
-            int adjustedIndex = index << 2;
-            hashArray[adjustedIndex] = (byte) value;
-            hashArray[adjustedIndex + 1] = (byte) (value >> 8);
-            hashArray[adjustedIndex + 2] = (byte) (value >> 16);
-            hashArray[adjustedIndex + 3] = (byte) (value >> 24);
-        }
-    }
-
-    private int findAndRemoveHash(Object key) {
-        int hashIndex = getHashIndex(key);
-        int index = getHashArray(hashIndex) - 1;
-        if (index != -1) {
-            Object entryKey = getKey(index);
-            if (compareKeys(key, entryKey)) {
-                Object value = getRawValue(index);
-                int nextIndex = -1;
-                if (value instanceof CollisionLink) {
-                    CollisionLink collisionLink = (CollisionLink) value;
-                    nextIndex = collisionLink.next;
-                }
-                setHashArray(hashIndex, nextIndex + 1);
-                return index;
-            } else {
-                Object entryValue = getRawValue(index);
-                if (entryValue instanceof CollisionLink) {
-                    return findAndRemoveWithCollision(key, (CollisionLink) entryValue, index);
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    private int findAndRemoveWithCollision(Object key, CollisionLink initialEntryValue, int initialIndexValue) {
-        int index;
-        Object entryKey;
-        CollisionLink entryValue = initialEntryValue;
-        int lastIndex = initialIndexValue;
-        while (true) {
-            CollisionLink collisionLink = entryValue;
-            index = collisionLink.next;
-            entryKey = getKey(index);
-            if (compareKeys(key, entryKey)) {
-                Object value = getRawValue(index);
-                if (value instanceof CollisionLink) {
-                    CollisionLink thisCollisionLink = (CollisionLink) value;
-                    setRawValue(lastIndex, new CollisionLink(collisionLink.value, thisCollisionLink.next));
-                } else {
-                    setRawValue(lastIndex, collisionLink.value);
-                }
-                return index;
-            } else {
-                Object value = getRawValue(index);
-                if (value instanceof CollisionLink) {
-                    entryValue = (CollisionLink) getRawValue(index);
-                    lastIndex = index;
-                } else {
-                    return -1;
-                }
-            }
-        }
-    }
-
-    private int getHashIndex(Object key) {
-        int hash;
-        if (strategy != null && strategy != Equivalence.DEFAULT) {
-            if (strategy == Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
-                hash = System.identityHashCode(key);
-            } else {
-                hash = strategy.hashCode(key);
-            }
-        } else {
-            hash = key.hashCode();
-        }
-        hash = hash ^ (hash >>> 16);
-        return hash & (getHashTableSize() - 1);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public V put(K key, V value) {
-        if (key == null) {
-            throw new UnsupportedOperationException("null not supported as key!");
-        }
-        int index = find(key);
-        if (index != -1) {
-            Object oldValue = getValue(index);
-            setValue(index, value);
-            return (V) oldValue;
-        }
-
-        int nextEntryIndex = totalEntries;
-        if (entries == null) {
-            entries = new Object[INITIAL_CAPACITY << 1];
-        } else if (entries.length == nextEntryIndex << 1) {
-            grow();
-
-            assert entries.length > totalEntries << 1;
-            // Can change if grow is actually compressing.
-            nextEntryIndex = totalEntries;
-        }
-
-        setKey(nextEntryIndex, key);
-        setValue(nextEntryIndex, value);
-        totalEntries++;
-
-        if (hasHashArray()) {
-            // Rehash on collision if hash table is more than three quarters full.
-            boolean rehashOnCollision = (getHashTableSize() < (size() + (size() >> 1)));
-            putHashEntry(key, nextEntryIndex, rehashOnCollision);
-        } else if (totalEntries > getHashThreshold()) {
-            createHash();
-        }
-
-        return null;
-    }
-
-    /**
-     * Number of entries above which a hash table should be constructed.
-     */
-    private int getHashThreshold() {
-        if (strategy == null || strategy == Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE) {
-            return HASH_THRESHOLD_IDENTITY_COMPARE;
-        } else {
-            return HASH_THRESHOLD;
-        }
-    }
-
-    private void grow() {
-        int entriesLength = entries.length;
-        int newSize = (entriesLength >> 1) + Math.max(MIN_CAPACITY_INCREASE, entriesLength >> 2);
-        if (newSize > MAX_ELEMENT_COUNT) {
-            throw new UnsupportedOperationException("map grown too large!");
-        }
-        Object[] newEntries = new Object[newSize << 1];
-        System.arraycopy(entries, 0, newEntries, 0, entriesLength);
-        entries = newEntries;
-        if ((entriesLength < LARGE_HASH_THRESHOLD && newEntries.length >= LARGE_HASH_THRESHOLD) ||
-                        (entriesLength < VERY_LARGE_HASH_THRESHOLD && newEntries.length > VERY_LARGE_HASH_THRESHOLD)) {
-            // Rehash in order to change number of bits reserved for hash indices.
-            createHash();
-        }
-    }
-
-    /**
-     * Compresses the graph if there is a large number of deleted entries and returns the translated
-     * new next index.
-     */
-    private int maybeCompress(int nextIndex) {
-        if (entries.length != INITIAL_CAPACITY << 1 && deletedEntries >= (totalEntries >> 1) + (totalEntries >> 2)) {
-            return compressLarge(nextIndex);
-        }
-        return nextIndex;
-    }
-
-    /**
-     * Compresses the graph and returns the translated new next index.
-     */
-    private int compressLarge(int nextIndex) {
-        int size = INITIAL_CAPACITY;
-        int remaining = totalEntries - deletedEntries;
-
-        while (size <= remaining) {
-            size += Math.max(MIN_CAPACITY_INCREASE, size >> 1);
-        }
-
-        Object[] newEntries = new Object[size << 1];
-        int z = 0;
-        int newNextIndex = remaining;
-        for (int i = 0; i < totalEntries; ++i) {
-            Object key = getKey(i);
-            if (i == nextIndex) {
-                newNextIndex = z;
-            }
-            if (key != null) {
-                newEntries[z << 1] = key;
-                newEntries[(z << 1) + 1] = getValue(i);
-                z++;
-            }
-        }
-
-        this.entries = newEntries;
-        totalEntries = z;
-        deletedEntries = 0;
-        if (z <= getHashThreshold()) {
-            this.hashArray = null;
-        } else {
-            createHash();
-        }
-        return newNextIndex;
-    }
-
-    private int getHashTableSize() {
-        if (entries.length < LARGE_HASH_THRESHOLD) {
-            return hashArray.length;
-        } else if (entries.length < VERY_LARGE_HASH_THRESHOLD) {
-            return hashArray.length >> 1;
-        } else {
-            return hashArray.length >> 2;
-        }
-    }
-
-    private void createHash() {
-        int entryCount = size();
-
-        // Calculate smallest 2^n that is greater number of entries.
-        int size = getHashThreshold();
-        while (size <= entryCount) {
-            size <<= 1;
-        }
-
-        // Give extra size to avoid collisions.
-        size <<= 1;
-
-        if (this.entries.length >= VERY_LARGE_HASH_THRESHOLD) {
-            // Every entry has 4 bytes.
-            size <<= 2;
-        } else if (this.entries.length >= LARGE_HASH_THRESHOLD) {
-            // Every entry has 2 bytes.
-            size <<= 1;
-        } else {
-            // Entries are very small => give extra size to further reduce collisions.
-            size <<= 1;
-        }
-
-        hashArray = new byte[size];
-        for (int i = 0; i < totalEntries; i++) {
-            Object entryKey = getKey(i);
-            if (entryKey != null) {
-                putHashEntry(entryKey, i, false);
-            }
-        }
-    }
-
-    private void putHashEntry(Object key, int entryIndex, boolean rehashOnCollision) {
-        int hashIndex = getHashIndex(key);
-        int oldIndex = getHashArray(hashIndex) - 1;
-        if (oldIndex != -1 && rehashOnCollision) {
-            this.createHash();
-            return;
-        }
-        setHashArray(hashIndex, entryIndex + 1);
-        Object value = getRawValue(entryIndex);
-        if (oldIndex != -1) {
-            assert entryIndex != oldIndex : "this cannot happend and would create an endless collision link cycle";
-            if (value instanceof CollisionLink) {
-                CollisionLink collisionLink = (CollisionLink) value;
-                setRawValue(entryIndex, new CollisionLink(collisionLink.value, oldIndex));
-            } else {
-                setRawValue(entryIndex, new CollisionLink(getRawValue(entryIndex), oldIndex));
-            }
-        } else {
-            if (value instanceof CollisionLink) {
-                CollisionLink collisionLink = (CollisionLink) value;
-                setRawValue(entryIndex, collisionLink.value);
-            }
-        }
-    }
-
-    @Override
-    public int size() {
-        return totalEntries - deletedEntries;
-    }
-
-    @Override
-    public boolean containsKey(K key) {
-        return find(key) != -1;
-    }
-
-    @Override
-    public void clear() {
-        entries = null;
-        hashArray = null;
-        totalEntries = deletedEntries = 0;
-    }
-
-    private boolean hasHashArray() {
-        return hashArray != null;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public V removeKey(K key) {
-        if (key == null) {
-            throw new UnsupportedOperationException("null not supported as key!");
-        }
-        int index;
-        if (hasHashArray()) {
-            index = this.findAndRemoveHash(key);
-        } else {
-            index = this.findLinear(key);
-        }
-
-        if (index != -1) {
-            Object value = getValue(index);
-            remove(index);
-            return (V) value;
-        }
-        return null;
-    }
-
-    /**
-     * Removes the element at the specific index and returns the index of the next element. This can
-     * be a different value if graph compression was triggered.
-     */
-    private int remove(int indexToRemove) {
-        int index = indexToRemove;
-        int entriesAfterIndex = totalEntries - index - 1;
-        int result = index + 1;
-
-        // Without hash array, compress immediately.
-        if (entriesAfterIndex <= COMPRESS_IMMEDIATE_CAPACITY && !hasHashArray()) {
-            while (index < totalEntries - 1) {
-                setKey(index, getKey(index + 1));
-                setRawValue(index, getRawValue(index + 1));
-                index++;
-            }
-            result--;
-        }
-
-        setKey(index, null);
-        setRawValue(index, null);
-        if (index == totalEntries - 1) {
-            // Make sure last element is always non-null.
-            totalEntries--;
-            while (index > 0 && getKey(index - 1) == null) {
-                totalEntries--;
-                deletedEntries--;
-                index--;
-            }
-        } else {
-            deletedEntries++;
-            result = maybeCompress(result);
-        }
-
-        return result;
-    }
-
-    private abstract class SparseMapIterator<E> implements Iterator<E> {
-
-        protected int current;
-
-        @Override
-        public boolean hasNext() {
-            return current < totalEntries;
-        }
-
-        @Override
-        public void remove() {
-            if (hasHashArray()) {
-                EconomicMapImpl.this.findAndRemoveHash(getKey(current - 1));
-            }
-            current = EconomicMapImpl.this.remove(current - 1);
-        }
-    }
-
-    @Override
-    public Iterable<V> getValues() {
-        return new Iterable<V>() {
-            @Override
-            public Iterator<V> iterator() {
-                return new SparseMapIterator<V>() {
-                    @SuppressWarnings("unchecked")
-                    @Override
-                    public V next() {
-                        Object result;
-                        while (true) {
-                            result = getValue(current);
-                            if (result == null && getKey(current) == null) {
-                                // values can be null, double-check if key is also null
-                                current++;
-                            } else {
-                                current++;
-                                break;
-                            }
-                        }
-                        return (V) result;
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
-    public Iterable<K> getKeys() {
-        return this;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return this.size() == 0;
-    }
-
-    @Override
-    public MapCursor<K, V> getEntries() {
-        return new MapCursor<K, V>() {
-            int current = -1;
-
-            @Override
-            public boolean advance() {
-                current++;
-                if (current >= totalEntries) {
-                    return false;
-                } else {
-                    while (EconomicMapImpl.this.getKey(current) == null) {
-                        // Skip over null entries
-                        current++;
-                    }
-                    return true;
-                }
-            }
-
-            @SuppressWarnings("unchecked")
-            @Override
-            public K getKey() {
-                return (K) EconomicMapImpl.this.getKey(current);
-            }
-
-            @SuppressWarnings("unchecked")
-            @Override
-            public V getValue() {
-                return (V) EconomicMapImpl.this.getValue(current);
-            }
-
-            @Override
-            public void remove() {
-                if (hasHashArray()) {
-                    EconomicMapImpl.this.findAndRemoveHash(EconomicMapImpl.this.getKey(current));
-                }
-                current = EconomicMapImpl.this.remove(current) - 1;
-            }
-        };
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
-        for (int i = 0; i < totalEntries; i++) {
-            Object entryKey = getKey(i);
-            if (entryKey != null) {
-                Object newValue = function.apply((K) entryKey, (V) getValue(i));
-                setValue(i, newValue);
-            }
-        }
-    }
-
-    private Object getKey(int index) {
-        return entries[index << 1];
-    }
-
-    private void setKey(int index, Object newValue) {
-        entries[index << 1] = newValue;
-    }
-
-    private void setValue(int index, Object newValue) {
-        Object oldValue = getRawValue(index);
-        if (oldValue instanceof CollisionLink) {
-            CollisionLink collisionLink = (CollisionLink) oldValue;
-            setRawValue(index, new CollisionLink(newValue, collisionLink.next));
-        } else {
-            setRawValue(index, newValue);
-        }
-    }
-
-    private void setRawValue(int index, Object newValue) {
-        entries[(index << 1) + 1] = newValue;
-    }
-
-    private Object getRawValue(int index) {
-        return entries[(index << 1) + 1];
-    }
-
-    private Object getValue(int index) {
-        Object object = getRawValue(index);
-        if (object instanceof CollisionLink) {
-            return ((CollisionLink) object).value;
-        }
-        return object;
-    }
-
-    private final boolean isSet;
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(isSet ? "set(size=" : "map(size=").append(size()).append(", {");
-        String sep = "";
-        MapCursor<K, V> cursor = getEntries();
-        while (cursor.advance()) {
-            builder.append(sep);
-            if (isSet) {
-                builder.append(cursor.getKey());
-            } else {
-                builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append(")");
-            }
-            sep = ",";
-        }
-        builder.append("})");
-        return builder.toString();
-    }
-
-    @Override
-    public Iterator<K> iterator() {
-        return new SparseMapIterator<K>() {
-            @SuppressWarnings("unchecked")
-            @Override
-            public K next() {
-                Object result;
-                while ((result = getKey(current++)) == null) {
-                    // skip null entries
-                }
-                return (K) result;
-            }
-        };
-    }
-
-    @Override
-    public boolean contains(K element) {
-        return containsKey(element);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean add(K element) {
-        return put(element, (V) element) == null;
-    }
-
-    @Override
-    public void remove(K element) {
-        removeKey(element);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicSet.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-import java.util.Iterator;
-
-/**
- * Memory efficient set data structure.
- *
- * @since 1.0
- */
-public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
-
-    /**
-     * Adds {@code element} to this set if it is not already present.
-     *
-     * @return {@code true} if this set did not already contain {@code element}.
-     * @since 1.0
-     */
-    boolean add(E element);
-
-    /**
-     * Removes {@code element} from this set if it is present. This set will not contain
-     * {@code element} once the call returns.
-     *
-     * @since 1.0
-     */
-    void remove(E element);
-
-    /**
-     * Removes all of the elements from this set. The set will be empty after this call returns.
-     *
-     * @since 1.0
-     */
-    void clear();
-
-    /**
-     * Adds all of the elements in {@code other} to this set if they're not already present.
-     *
-     * @since 1.0
-     */
-    default void addAll(EconomicSet<E> other) {
-        addAll(other.iterator());
-    }
-
-    /**
-     * Adds all of the elements in {@code values} to this set if they're not already present.
-     *
-     * @since 1.0
-     */
-    default void addAll(Iterable<E> values) {
-        addAll(values.iterator());
-    }
-
-    /**
-     * Adds all of the elements enumerated by {@code iterator} to this set if they're not already
-     * present.
-     *
-     * @since 1.0
-     */
-    default void addAll(Iterator<E> iterator) {
-        while (iterator.hasNext()) {
-            add(iterator.next());
-        }
-    }
-
-    /**
-     * Removes from this set all of its elements that are contained in {@code other}.
-     *
-     * @since 1.0
-     */
-    default void removeAll(EconomicSet<E> other) {
-        removeAll(other.iterator());
-    }
-
-    /**
-     * Removes from this set all of its elements that are contained in {@code values}.
-     *
-     * @since 1.0
-     */
-    default void removeAll(Iterable<E> values) {
-        removeAll(values.iterator());
-    }
-
-    /**
-     * Removes from this set all of its elements that are enumerated by {@code iterator}.
-     *
-     * @since 1.0
-     */
-    default void removeAll(Iterator<E> iterator) {
-        while (iterator.hasNext()) {
-            remove(iterator.next());
-        }
-    }
-
-    /**
-     * Removes from this set all of its elements that are not contained in {@code other}.
-     *
-     * @since 1.0
-     */
-    default void retainAll(EconomicSet<E> other) {
-        Iterator<E> iterator = iterator();
-        while (iterator.hasNext()) {
-            E key = iterator.next();
-            if (!other.contains(key)) {
-                iterator.remove();
-            }
-        }
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements with the
-     * default {@link Equivalence#DEFAULT} comparison strategy.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create() {
-        return EconomicSet.create(Equivalence.DEFAULT);
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create(Equivalence strategy) {
-        return EconomicMapImpl.create(strategy, true);
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements with the
-     * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
-     * specified collection.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create(int initialCapacity) {
-        return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements with the
-     * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
-     * specified collection.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
-        return EconomicSet.create(Equivalence.DEFAULT, c);
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements and
-     * initializes with the given capacity.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
-        return EconomicMapImpl.create(strategy, initialCapacity, true);
-    }
-
-    /**
-     * Creates a new set guaranteeing insertion order when iterating over its elements and inserts
-     * all elements of the specified collection.
-     *
-     * @since 1.0
-     */
-    static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
-        return EconomicMapImpl.create(strategy, c, true);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Equivalence.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-/**
- * Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
- * {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
- *
- * @since 1.0
- */
-public abstract class Equivalence {
-
-    /**
-     * Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()}
-     * for obtaining hash values. Do not change the logic of this class as it may be inlined in
-     * other places.
-     *
-     * @since 1.0
-     */
-    public static final Equivalence DEFAULT = new Equivalence() {
-
-        @Override
-        public boolean equals(Object a, Object b) {
-            return a.equals(b);
-        }
-
-        @Override
-        public int hashCode(Object o) {
-            return o.hashCode();
-        }
-    };
-
-    /**
-     * Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
-     * hash values. Do not change the logic of this class as it may be inlined in other places.
-     *
-     * @since 1.0
-     */
-    public static final Equivalence IDENTITY = new Equivalence() {
-
-        @Override
-        public boolean equals(Object a, Object b) {
-            return a == b;
-        }
-
-        @Override
-        public int hashCode(Object o) {
-            return o.hashCode();
-        }
-    };
-
-    /**
-     * Identity equivalence using {@code ==} to check equality and
-     * {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
-     * this class as it may be inlined in other places.
-     *
-     * @since 1.0
-     */
-    public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
-
-        @Override
-        public boolean equals(Object a, Object b) {
-            return a == b;
-        }
-
-        @Override
-        public int hashCode(Object o) {
-            return System.identityHashCode(o);
-        }
-    };
-
-    /**
-     * Subclass for creating custom equivalence definitions.
-     *
-     * @since 1.0
-     */
-    protected Equivalence() {
-    }
-
-    /**
-     * Returns {@code true} if the non-{@code null} arguments are equal to each other and
-     * {@code false} otherwise.
-     *
-     * @since 1.0
-     */
-    public abstract boolean equals(Object a, Object b);
-
-    /**
-     * Returns the hash code of a non-{@code null} argument {@code o}.
-     *
-     * @since 1.0
-     */
-    public abstract int hashCode(Object o);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/MapCursor.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-/**
- * Cursor to iterate over a mutable map.
- *
- * @since 1.0
- */
-public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
-    /**
-     * Remove the current entry from the map. May only be called once. After calling
-     * {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
-     * the current entry.
-     *
-     * @since 1.0
-     */
-    void remove();
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Pair.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-import java.util.Objects;
-
-/**
- * Utility class representing a pair of values.
- *
- * @since 1.0
- */
-public final class Pair<L, R> {
-
-    private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
-
-    private final L left;
-    private final R right;
-
-    /**
-     * Returns an empty pair.
-     *
-     * @since 1.0
-     */
-    @SuppressWarnings("unchecked")
-    public static <L, R> Pair<L, R> empty() {
-        return (Pair<L, R>) EMPTY;
-    }
-
-    /**
-     * Constructs a pair with its left value being {@code left}, or returns an empty pair if
-     * {@code left} is null.
-     *
-     * @return the constructed pair or an empty pair if {@code left} is null.
-     * @since 1.0
-     */
-    public static <L, R> Pair<L, R> createLeft(L left) {
-        if (left == null) {
-            return empty();
-        } else {
-            return new Pair<>(left, null);
-        }
-    }
-
-    /**
-     * Constructs a pair with its right value being {@code right}, or returns an empty pair if
-     * {@code right} is null.
-     *
-     * @return the constructed pair or an empty pair if {@code right} is null.
-     * @since 1.0
-     */
-    public static <L, R> Pair<L, R> createRight(R right) {
-        if (right == null) {
-            return empty();
-        } else {
-            return new Pair<>(null, right);
-        }
-    }
-
-    /**
-     * Constructs a pair with its left value being {@code left}, and its right value being
-     * {@code right}, or returns an empty pair if both inputs are null.
-     *
-     * @return the constructed pair or an empty pair if both inputs are null.
-     * @since 1.0
-     */
-    public static <L, R> Pair<L, R> create(L left, R right) {
-        if (right == null && left == null) {
-            return empty();
-        } else {
-            return new Pair<>(left, right);
-        }
-    }
-
-    private Pair(L left, R right) {
-        this.left = left;
-        this.right = right;
-    }
-
-    /**
-     * Returns the left value of this pair.
-     *
-     * @since 1.0
-     */
-    public L getLeft() {
-        return left;
-    }
-
-    /**
-     * Returns the right value of this pair.
-     *
-     * @since 1.0
-     */
-    public R getRight() {
-        return right;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @since 1.0
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(left) + 31 * Objects.hashCode(right);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @since 1.0
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-
-        if (obj instanceof Pair) {
-            Pair<L, R> pair = (Pair<L, R>) obj;
-            return Objects.equals(left, pair.left) && Objects.equals(right, pair.right);
-        }
-
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @since 1.0
-     */
-    @Override
-    public String toString() {
-        return String.format("(%s, %s)", left, right);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicMap.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-/**
- * Unmodifiable memory efficient map data structure.
- *
- * @since 1.0
- */
-public interface UnmodifiableEconomicMap<K, V> {
-
-    /**
-     * Returns the value to which {@code key} is mapped, or {@code null} if this map contains no
-     * mapping for {@code key}.
-     *
-     * @since 1.0
-     */
-    V get(K key);
-
-    /**
-     * Returns the value to which {@code key} is mapped, or {@code defaultValue} if this map
-     * contains no mapping for {@code key}.
-     *
-     * @since 1.0
-     */
-    default V get(K key, V defaultValue) {
-        V v = get(key);
-        if (v == null) {
-            return defaultValue;
-        }
-        return v;
-    }
-
-    /**
-     * Returns {@code true} if this map contains a mapping for {@code key}.
-     *
-     * @since 1.0
-     */
-    boolean containsKey(K key);
-
-    /**
-     * Returns the number of key-value mappings in this map.
-     *
-     * @since 1.0
-     */
-    int size();
-
-    /**
-     * Returns {@code true} if this map contains no key-value mappings.
-     *
-     * @since 1.0
-     */
-    boolean isEmpty();
-
-    /**
-     * Returns a {@link Iterable} view of the values contained in this map.
-     *
-     * @since 1.0
-     */
-    Iterable<V> getValues();
-
-    /**
-     * Returns a {@link Iterable} view of the keys contained in this map.
-     *
-     * @since 1.0
-     */
-    Iterable<K> getKeys();
-
-    /**
-     * Returns a {@link UnmodifiableMapCursor} view of the mappings contained in this map.
-     *
-     * @since 1.0
-     */
-    UnmodifiableMapCursor<K, V> getEntries();
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicSet.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-/**
- * Unmodifiable memory efficient set data structure.
- *
- * @since 1.0
- */
-public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
-
-    /**
-     * Returns {@code true} if this set contains a mapping for the {@code element}.
-     *
-     * @since 1.0
-     */
-    boolean contains(E element);
-
-    /**
-     * Returns the number of elements in this set.
-     *
-     * @since 1.0
-     */
-    int size();
-
-    /**
-     * Returns {@code true} if this set contains no elements.
-     *
-     * @since 1.0
-     */
-    boolean isEmpty();
-
-    /**
-     * Stores all of the elements in this set into {@code target}. An
-     * {@link UnsupportedOperationException} will be thrown if the length of {@code target} does not
-     * match the size of this set.
-     *
-     * @return an array containing all the elements in this set.
-     * @throws UnsupportedOperationException if the length of {@code target} does not equal the size
-     *             of this set.
-     * @since 1.0
-     */
-    default E[] toArray(E[] target) {
-        if (target.length != size()) {
-            throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
-        }
-
-        int index = 0;
-        for (E element : this) {
-            target[index++] = element;
-        }
-
-        return target;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableMapCursor.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.collections;
-
-/**
- * Cursor to iterate over a map without changing its contents.
- *
- * @since 1.0
- */
-public interface UnmodifiableMapCursor<K, V> {
-    /**
-     * Advances to the next entry.
-     *
-     * @return {@code true} if a next entry exists, {@code false} if there is no next entry.
-     * @since 1.0
-     */
-    boolean advance();
-
-    /**
-     * The key of the current entry.
-     *
-     * @since 1.0
-     */
-    K getKey();
-
-    /**
-     * The value of the current entry.
-     *
-     * @since 1.0
-     */
-    V getValue();
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/package-info.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.
- */
-/**
- * The Graal-SDK collections package contains memory efficient data structures.
- *
- * @see org.graalvm.collections.EconomicMap
- * @see org.graalvm.collections.EconomicSet
- *
- * @since 1.0
- */
-package org.graalvm.collections;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java	Tue Apr 24 09:04:57 2018 -0700
@@ -206,12 +206,12 @@
     }
 
     @Override
-    protected void bfm(int size, Register dst, Register src, int r, int s) {
+    public void bfm(int size, Register dst, Register src, int r, int s) {
         super.bfm(size, dst, src, r, s);
     }
 
     @Override
-    protected void ubfm(int size, Register dst, Register src, int r, int s) {
+    public void ubfm(int size, Register dst, Register src, int r, int s) {
         super.ubfm(size, dst, src, r, s);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,6 +35,7 @@
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BLR;
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
+import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CAS;
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
@@ -118,6 +119,9 @@
 import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
 import org.graalvm.compiler.debug.GraalError;
 
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.aarch64.AArch64.CPUFeature;
+import jdk.vm.ci.aarch64.AArch64.Flag;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.TargetDescription;
 
@@ -471,6 +475,9 @@
     private static final int BarrierOp = 0xD503301F;
     private static final int BarrierKindOffset = 8;
 
+    private static final int CASAcquireOffset = 22;
+    private static final int CASReleaseOffset = 15;
+
     /**
      * Encoding for all instructions.
      */
@@ -501,6 +508,8 @@
         LDP(0b1 << 22),
         STP(0b0 << 22),
 
+        CAS(0x08A07C00),
+
         ADR(0x00000000),
         ADRP(0x80000000),
 
@@ -740,6 +749,14 @@
         super(target);
     }
 
+    public boolean supports(CPUFeature feature) {
+        return ((AArch64) target.arch).getFeatures().contains(feature);
+    }
+
+    public boolean isFlagSet(Flag flag) {
+        return ((AArch64) target.arch).getFlags().contains(flag);
+    }
+
     /* Conditional Branch (5.2.1) */
 
     /**
@@ -1311,6 +1328,20 @@
         emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
     }
 
+    /* Compare And Swap */
+    public void cas(int size, Register rs, Register rt, Register rn, boolean acquire, boolean release) {
+        assert size == 32 || size == 64;
+        int transferSize = NumUtil.log2Ceil(size / 8);
+        compareAndSwapInstruction(CAS, rs, rt, rn, transferSize, acquire, release);
+    }
+
+    private void compareAndSwapInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize, boolean acquire, boolean release) {
+        assert log2TransferSize >= 0 && log2TransferSize < 4;
+        assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
+        int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
+        emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt) | (acquire ? 1 : 0) << CASAcquireOffset | (release ? 1 : 0) << CASReleaseOffset);
+    }
+
     /* PC-relative Address Calculation (5.4.4) */
 
     /**
@@ -1576,7 +1607,7 @@
      * @param r must be in the range 0 to size - 1
      * @param s must be in the range 0 to size - 1
      */
-    protected void bfm(int size, Register dst, Register src, int r, int s) {
+    public void bfm(int size, Register dst, Register src, int r, int s) {
         bitfieldInstruction(BFM, dst, src, r, s, generalFromSize(size));
     }
 
@@ -1589,7 +1620,7 @@
      * @param r must be in the range 0 to size - 1
      * @param s must be in the range 0 to size - 1
      */
-    protected void ubfm(int size, Register dst, Register src, int r, int s) {
+    public void ubfm(int size, Register dst, Register src, int r, int s) {
         bitfieldInstruction(UBFM, dst, src, r, s, generalFromSize(size));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import java.util.List;
 import java.util.Objects;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.graph.NodeSourcePosition;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/SourceStackTraceBailoutException.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/SourceStackTraceBailoutException.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,8 +32,8 @@
 public abstract class SourceStackTraceBailoutException extends PermanentBailoutException {
     private static final long serialVersionUID = 2144811793442316776L;
 
-    public static SourceStackTraceBailoutException create(Throwable cause, String format, StackTraceElement[] elements) {
-        return new SourceStackTraceBailoutException(cause, format) {
+    public static SourceStackTraceBailoutException create(Throwable cause, String reason, StackTraceElement[] elements) {
+        return new SourceStackTraceBailoutException(cause, reason) {
 
             private static final long serialVersionUID = 6279381376051787907L;
 
@@ -46,7 +46,7 @@
         };
     }
 
-    private SourceStackTraceBailoutException(Throwable cause, String format) {
-        super(cause, format);
+    private SourceStackTraceBailoutException(Throwable cause, String reason) {
+        super(cause, "%s", reason);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.lir.Variable;
 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
+import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Compare;
@@ -51,13 +52,14 @@
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Move;
-import org.graalvm.compiler.lir.aarch64.AArch64Move.CompareAndSwapOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
 import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGenerator;
 import org.graalvm.compiler.phases.util.Providers;
 
+import jdk.vm.ci.aarch64.AArch64;
 import jdk.vm.ci.aarch64.AArch64Kind;
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.RegisterValue;
@@ -423,6 +425,21 @@
     }
 
     @Override
+    public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
+        LIRKind resultKind = LIRKind.value(AArch64Kind.DWORD);
+        // DMS TODO: check calling conversion and registers used
+        RegisterValue res = AArch64.r0.asValue(resultKind);
+        RegisterValue cnt1 = AArch64.r1.asValue(length1.getValueKind());
+        RegisterValue cnt2 = AArch64.r2.asValue(length2.getValueKind());
+        emitMove(cnt1, length1);
+        emitMove(cnt2, length2);
+        append(new AArch64ArrayCompareToOp(this, kind1, kind2, res, array1, array2, cnt1, cnt2));
+        Variable result = newVariable(resultKind);
+        emitMove(result, res);
+        return result;
+    }
+
+    @Override
     public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
         Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
         append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.graalvm.compiler.core.aarch64;
+
+import jdk.vm.ci.aarch64.AArch64Kind;
+
+import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.SignExtendNode;
+import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
+import org.graalvm.compiler.nodes.extended.GuardingNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+/**
+ * AArch64-specific subclass of ReadNode that knows how to merge ZeroExtend and SignExtend into the
+ * read.
+ */
+
+@NodeInfo
+public class AArch64ReadNode extends ReadNode {
+    public static final NodeClass<AArch64ReadNode> TYPE = NodeClass.create(AArch64ReadNode.class);
+    private final IntegerStamp accessStamp;
+    private final boolean isSigned;
+
+    public AArch64ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck,
+                    FrameState stateBefore, IntegerStamp accessStamp, boolean isSigned) {
+        super(TYPE, address, location, stamp, guard, barrierType, nullCheck, stateBefore);
+        this.accessStamp = accessStamp;
+        this.isSigned = isSigned;
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool gen) {
+        AArch64LIRGenerator lirgen = (AArch64LIRGenerator) gen.getLIRGeneratorTool();
+        AArch64ArithmeticLIRGenerator arithgen = (AArch64ArithmeticLIRGenerator) lirgen.getArithmetic();
+        AArch64Kind readKind = (AArch64Kind) lirgen.getLIRKind(accessStamp).getPlatformKind();
+        int resultBits = ((IntegerStamp) stamp(NodeView.DEFAULT)).getBits();
+        gen.setResult(this, arithgen.emitExtendMemory(isSigned, readKind, resultBits, (AArch64AddressValue) gen.operand(getAddress()), gen.state(this)));
+    }
+
+    /**
+     * replace a ReadNode with an AArch64-specific variant which knows how to merge a downstream
+     * zero or sign extend into the read operation.
+     *
+     * @param readNode
+     */
+    public static void replace(ReadNode readNode) {
+        assert readNode.getUsageCount() == 1;
+        assert readNode.getUsageAt(0) instanceof ZeroExtendNode || readNode.getUsageAt(0) instanceof SignExtendNode;
+
+        ValueNode usage = (ValueNode) readNode.getUsageAt(0);
+        boolean isSigned = usage instanceof SignExtendNode;
+        IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp());
+
+        AddressNode address = readNode.getAddress();
+        LocationIdentity location = readNode.getLocationIdentity();
+        Stamp stamp = usage.stamp(NodeView.DEFAULT);
+        GuardingNode guard = readNode.getGuard();
+        BarrierType barrierType = readNode.getBarrierType();
+        boolean nullCheck = readNode.getNullCheck();
+        FrameState stateBefore = readNode.stateBefore();
+        AArch64ReadNode clone = new AArch64ReadNode(address, location, stamp, guard, barrierType, nullCheck, stateBefore, accessStamp, isSigned);
+        StructuredGraph graph = readNode.graph();
+        graph.add(clone);
+        // splice out the extend node
+        usage.replaceAtUsagesAndDelete(readNode);
+        // swap the clone for the read
+        graph.replaceFixedWithFixed(readNode, clone);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.graalvm.compiler.core.aarch64;
+
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.calc.SignExtendNode;
+import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.phases.Phase;
+
+/**
+ * AArch64-specific phase which substitutes certain read nodes with arch-specific variants in order
+ * to allow merging of zero and sign extension into the read operation.
+ */
+
+public class AArch64ReadReplacementPhase extends Phase {
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Node node : graph.getNodes()) {
+            // don't process nodes we just added
+            if (node instanceof AArch64ReadNode) {
+                continue;
+            }
+            if (node instanceof ReadNode) {
+                ReadNode readNode = (ReadNode) node;
+                if (readNode.hasExactlyOneUsage()) {
+                    Node usage = readNode.getUsageAt(0);
+                    if (usage instanceof ZeroExtendNode || usage instanceof SignExtendNode) {
+                        AArch64ReadNode.replace(readNode);
+                    }
+                }
+            }
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,14 +22,37 @@
  */
 package org.graalvm.compiler.core.aarch64;
 
+import java.util.ListIterator;
+
 import org.graalvm.compiler.java.DefaultSuitesCreator;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.Phase;
+import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
 
 public class AArch64SuitesCreator extends DefaultSuitesCreator {
+    private final Class<? extends Phase> insertReadReplacementBefore;
 
-    public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+    public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, Class<? extends Phase> insertReadReplacementBefore) {
         super(compilerConfiguration, plugins);
+        this.insertReadReplacementBefore = insertReadReplacementBefore;
     }
 
+    @Override
+    public Suites createSuites(OptionValues options) {
+        Suites suites = super.createSuites(options);
+
+        ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(insertReadReplacementBefore);
+        // Put AArch64ReadReplacementPhase right before the SchedulePhase
+        while (PhaseSuite.findNextPhase(findPhase, insertReadReplacementBefore)) {
+            // Search for last occurrence of SchedulePhase
+        }
+        findPhase.previous();
+        findPhase.add(new AArch64ReadReplacementPhase());
+        return suites;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.lir.VirtualStackSlot;
 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -262,6 +262,9 @@
     @Option(help = "Track the NodeSourcePosition.", type = OptionType.Debug)
     public static final OptionKey<Boolean> TrackNodeSourcePosition = new OptionKey<>(false);
 
+    @Option(help = "Track source stack trace where a node was inserted into the graph.", type = OptionType.Debug)
+    public static final OptionKey<Boolean> TrackNodeInsertion = new OptionKey<>(false);
+
     @Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug)
     public static final OptionKey<Boolean> MatchExpressions = new OptionKey<>(true);
 
@@ -276,7 +279,10 @@
 
     @Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
     public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
-    @Option(help = "Enable tracing of inlining decision.", type = OptionType.Debug)
+
+    @Option(help = "file:doc-files/TraceInliningHelp.txt", type = OptionType.Debug)
     public static final OptionKey<Boolean> TraceInlining = new OptionKey<>(false);
 
+    @Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)
+    public static final OptionKey<Boolean> TraceInliningForStubsAndSnippets = new OptionKey<>(false);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/PermanentBailoutException.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/PermanentBailoutException.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
     }
 
     public PermanentBailoutException(String reason) {
-        super(true, reason);
+        super(true, "%s", reason);
     }
 
     public PermanentBailoutException(Throwable cause, String format, Object... args) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/RegisterAllocationConfig.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/RegisterAllocationConfig.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.core.common.alloc;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.GraalOptions;
 
 import jdk.vm.ci.code.Register;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/doc-files/TraceInliningHelp.txt	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,8 @@
+Enable tracing of inlining decisions.
+Output format:
+  compilation of 'Signature of the compilation root method':
+    at 'Signature of the root method' ['Bytecode index']: <'Phase'> 'Child method signature': 'Decision made about this callsite'
+      at 'Signature of the child method' ['Bytecode index']: 
+         |--<'Phase 1'> 'Grandchild method signature': 'First decision made about this callsite'
+         \--<'Phase 2'> 'Grandchild method signature': 'Second decision made about this callsite'
+      at 'Signature of the child method' ['Bytecode index']: <'Phase'> 'Another grandchild method signature': 'The only decision made about this callsite.'
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,7 +23,7 @@
 package org.graalvm.compiler.core.common.spi;
 
 import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.ValueKindFactory;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/FrequencyEncoder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/FrequencyEncoder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 
 /**
  * Creates an array of T objects order by the occurrence frequency of each object. The most
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.core.common.util;
-
-import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.graalvm.compiler.debug.GraalError;
-
-/**
- * Reflection based access to the Module API introduced by JDK 9. This allows the API to be used in
- * code that must be compiled on a JDK prior to 9. Use of this class must be guarded by a test for
- * JDK 9 or later. For example:
- *
- * <pre>
- * if (Util.JAVA_SPECIFICATION_VERSION >= 9) {
- *     // Use of ModuleAPI
- * }
- * </pre>
- */
-public final class ModuleAPI {
-
-    public ModuleAPI(Class<?> declaringClass, String name, Class<?>... parameterTypes) {
-        try {
-            this.method = declaringClass.getMethod(name, parameterTypes);
-        } catch (Exception e) {
-            throw new GraalError(e);
-        }
-    }
-
-    public final Method method;
-
-    public Class<?> getReturnType() {
-        return method.getReturnType();
-    }
-
-    /**
-     * {@code Class.getModule()}.
-     */
-    public static final ModuleAPI getModule;
-
-    /**
-     * {@code java.lang.Module.getResourceAsStream(String)}.
-     */
-    public static final ModuleAPI getResourceAsStream;
-
-    /**
-     * {@code java.lang.Module.isExported(String, Module)}.
-     */
-    public static final ModuleAPI isExportedTo;
-
-    /**
-     * Invokes the static Module API method represented by this object.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T invokeStatic(Object... args) {
-        checkAvailability();
-        assert Modifier.isStatic(method.getModifiers());
-        try {
-            return (T) method.invoke(null, args);
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-            throw new GraalError(e);
-        }
-    }
-
-    /**
-     * Invokes the non-static Module API method represented by this object.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T invoke(Object receiver, Object... args) {
-        checkAvailability();
-        assert !Modifier.isStatic(method.getModifiers());
-        try {
-            return (T) method.invoke(receiver, args);
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-            throw new GraalError(e);
-        }
-    }
-
-    private void checkAvailability() throws GraalError {
-        if (method == null) {
-            throw new GraalError("Cannot use Module API on JDK " + JAVA_SPECIFICATION_VERSION);
-        }
-    }
-
-    static {
-        if (JAVA_SPECIFICATION_VERSION >= 9) {
-            getModule = new ModuleAPI(Class.class, "getModule");
-            Class<?> moduleClass = getModule.getReturnType();
-            getResourceAsStream = new ModuleAPI(moduleClass, "getResourceAsStream", String.class);
-            isExportedTo = new ModuleAPI(moduleClass, "isExported", String.class, moduleClass);
-        } else {
-            ModuleAPI unavailable = new ModuleAPI();
-            getModule = unavailable;
-            getResourceAsStream = unavailable;
-            isExportedTo = unavailable;
-        }
-    }
-
-    private ModuleAPI() {
-        method = null;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java	Tue Apr 24 09:04:57 2018 -0700
@@ -58,9 +58,9 @@
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.core.match.ComplexMatchResult;
 import org.graalvm.compiler.core.match.MatchRule;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Tue Apr 24 09:04:57 2018 -0700
@@ -80,7 +80,7 @@
 import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
 import org.graalvm.compiler.phases.verify.VerifyVirtualizableUsage;
 import org.graalvm.compiler.runtime.RuntimeProvider;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Test;
@@ -103,14 +103,6 @@
  */
 public class CheckGraalInvariants extends GraalCompilerTest {
 
-    public CheckGraalInvariants() {
-        try {
-            Class.forName("java.lang.management.ManagementFactory");
-        } catch (ClassNotFoundException ex) {
-            Assume.assumeNoException("cannot run without java.management JDK9 module", ex);
-        }
-    }
-
     private static boolean shouldVerifyEquals(ResolvedJavaMethod m) {
         if (m.getName().equals("identityEquals")) {
             ResolvedJavaType c = m.getDeclaringClass();
@@ -148,7 +140,7 @@
         }
 
         protected boolean shouldLoadClass(String className) {
-            return !className.equals("module-info");
+            return !className.equals("module-info") && !className.startsWith("META-INF.versions.");
         }
 
         protected void handleClassLoadingException(Throwable t) {
@@ -191,7 +183,7 @@
                     for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
                         final ZipEntry zipEntry = entry.nextElement();
                         String name = zipEntry.getName();
-                        if (name.endsWith(".class")) {
+                        if (name.endsWith(".class") && !name.startsWith("META-INF/versions/")) {
                             String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
                             if (isInNativeImage(className)) {
                                 /*
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,7 +27,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.core.test;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Scope;
 import org.graalvm.compiler.debug.DebugOptions;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,6 @@
 import static org.graalvm.compiler.core.common.GraalOptions.OptAssumptions;
 import static org.junit.Assert.assertNotNull;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
 import org.graalvm.compiler.nodes.FullInfopointNode;
@@ -37,6 +35,7 @@
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Test;
 
 import jdk.vm.ci.code.site.Call;
 import jdk.vm.ci.code.site.Infopoint;
@@ -50,6 +49,11 @@
 
     public static final String[] STRINGS = new String[]{"world", "everyone", "you"};
 
+    public InfopointReasonTest() {
+        // Call testMethod to ensure all method references are resolved.
+        testMethod();
+    }
+
     public String testMethod() {
         StringBuilder sb = new StringBuilder("Hello ");
         for (String s : STRINGS) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -116,6 +116,7 @@
 
     @Test
     public void testCompiled() throws IOException {
+        Assume.assumeFalse("Crashes on AArch64 (GR-8351)", System.getProperty("os.arch").equalsIgnoreCase("aarch64"));
         ResolvedJavaMethod getMethod = asResolvedJavaMethod(getMethod(ByteBuffer.class, "get", new Class<?>[]{}));
         ResolvedJavaType mbbClass = getMetaAccess().lookupJavaType(MappedByteBuffer.class);
         ResolvedJavaMethod getMethodImpl = mbbClass.findUniqueConcreteMethod(getMethod).getResult();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReferenceGetLoopTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReferenceGetLoopTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.memory.Access;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ResolvedJavaField;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,12 +31,13 @@
 import java.util.Map;
 import java.util.Properties;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionDescriptor;
 import org.graalvm.compiler.options.OptionDescriptors;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 
 /**
@@ -108,8 +109,8 @@
             ParameterizedType pt = (ParameterizedType) declaredType;
             Type[] actualTypeArguments = pt.getActualTypeArguments();
             assert actualTypeArguments.length == 1;
-            Class<?> optionType = (Class<?>) actualTypeArguments[0];
-            descriptors.put(fieldName, OptionDescriptor.create(fieldName, optionType, help, declaringClass, fieldName, (OptionKey<?>) f.get(null)));
+            Class<?> optionValueType = (Class<?>) actualTypeArguments[0];
+            descriptors.put(fieldName, OptionDescriptor.create(fieldName, OptionType.Debug, optionValueType, help, declaringClass, fieldName, (OptionKey<?>) f.get(null)));
         } catch (IllegalAccessException | NoSuchFieldException e) {
             throw new IllegalArgumentException(e);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampMemoryAccessTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampMemoryAccessTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,6 @@
 
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.JavaConstant;
@@ -36,21 +35,23 @@
  */
 public class StampMemoryAccessTest extends GraalCompilerTest {
 
-    @Ignore("not all JVMCI versions are safe yet")
     @Test
     public void testReadPrimitive() {
         MemoryAccessProvider memory = getConstantReflection().getMemoryAccessProvider();
-        JavaConstant base = getSnippetReflection().forObject("");
         Stamp stamp = StampFactory.forKind(JavaKind.Long);
-        assertTrue(stamp.readConstant(memory, base, 128) == null);
+        JavaConstant objectBase = getSnippetReflection().forObject("");
+        assertTrue(stamp.readConstant(memory, objectBase, 128) == null);
+        JavaConstant arrayBase = getSnippetReflection().forObject(new int[]{});
+        assertTrue(stamp.readConstant(memory, arrayBase, 128) == null);
     }
 
-    @Ignore("not all JVMCI versions are safe yet")
     @Test
     public void testReadObject() {
         MemoryAccessProvider memory = getConstantReflection().getMemoryAccessProvider();
-        JavaConstant base = getSnippetReflection().forObject("");
         Stamp stamp = StampFactory.forKind(JavaKind.Object);
-        assertTrue(stamp.readConstant(memory, base, 128) == null);
+        JavaConstant objectBase = getSnippetReflection().forObject("");
+        assertTrue(stamp.readConstant(memory, objectBase, 128) == null);
+        JavaConstant arrayBase = getSnippetReflection().forObject(new int[]{});
+        assertTrue(stamp.readConstant(memory, arrayBase, 128) == null);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.JavaConstant;
@@ -405,6 +406,8 @@
      */
     @Test
     public void testNewNode() {
+        // Trackking of creation interferes with escape analysis
+        Assume.assumeFalse(Node.TRACK_CREATION_POSITION);
         testEscapeAnalysis("testNewNodeSnippet", null, false);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,9 +22,11 @@
  */
 package org.graalvm.compiler.core.test.inlining;
 
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugDumpScope;
+import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.Invoke;
@@ -32,18 +34,22 @@
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.StructuredGraph.Builder;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
 
 import jdk.vm.ci.code.site.InfopointReason;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
+import java.util.regex.Pattern;
+
 public class InliningTest extends GraalCompilerTest {
 
     @Test
@@ -198,6 +204,40 @@
         assertFewMethodInfopoints(assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet", true)));
     }
 
+    public static void traceInliningTest() {
+        callTrivial();
+    }
+
+    private static void callTrivial() {
+        callNonTrivial();
+    }
+
+    private static double callNonTrivial() {
+        double x = 0.0;
+        for (int i = 0; i < 10; i++) {
+            x += i * 1.21;
+        }
+        return x;
+    }
+
+    @Test
+    @SuppressWarnings("try")
+    public void testTracing() {
+        OptionValues options = new OptionValues(getInitialOptions(), GraalOptions.TraceInlining, true);
+        StructuredGraph graph;
+        try (TTY.Filter f = new TTY.Filter()) {
+            graph = getGraph("traceInliningTest", options, false);
+        }
+        String inliningTree = graph.getInliningLog().formatAsTree(false);
+        String expectedRegex = "compilation of org.graalvm.compiler.core.test.inlining.InliningTest.traceInliningTest.*: \\R" +
+                        "  at .*org.graalvm.compiler.core.test.inlining.InliningTest.traceInliningTest.*: <GraphBuilderPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callTrivial.*: yes, inline method\\R" +
+                        "    at .*org.graalvm.compiler.core.test.inlining.InliningTest.callTrivial.*: .*\\R" +
+                        "       .*<GraphBuilderPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callNonTrivial.*: .*(.*\\R)*" +
+                        "       .*<InliningPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callNonTrivial.*: .*(.*\\R)*";
+        Pattern expectedPattern = Pattern.compile(expectedRegex, Pattern.MULTILINE);
+        Assert.assertTrue("Got: " + inliningTree, expectedPattern.matcher(inliningTree).matches());
+    }
+
     @SuppressWarnings("all")
     public static int invokeLeafClassMethodSnippet(SubClassA subClassA) {
         return subClassA.publicFinalMethod() + subClassA.publicNotOverriddenMethod() + subClassA.publicOverriddenMethod();
@@ -233,9 +273,13 @@
         return superClass.protectedOverriddenMethod();
     }
 
+    private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
+        return getGraph(snippet, null, eagerInfopointMode);
+    }
+
     @SuppressWarnings("try")
-    private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
-        DebugContext debug = getDebugContext();
+    private StructuredGraph getGraph(final String snippet, OptionValues options, final boolean eagerInfopointMode) {
+        DebugContext debug = options == null ? getDebugContext() : getDebugContext(options, null, null);
         try (DebugContext.Scope s = debug.scope("InliningTest", new DebugDumpScope(snippet, true))) {
             ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
             Builder builder = builder(method, AllowAssumptions.YES, debug);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.TTY;
@@ -137,7 +137,8 @@
         ResolvedJavaMethod calleeMethod = next.callTarget().targetMethod();
         for (int i = 0; i < inliningCount; i++) {
             next = callerGraph.getNodes(MethodCallTargetNode.TYPE).first().invoke();
-            EconomicSet<Node> canonicalizeNodes = InliningUtil.inlineForCanonicalization(next, calleeGraph, false, calleeMethod);
+            EconomicSet<Node> canonicalizeNodes = InliningUtil.inlineForCanonicalization(next, calleeGraph, false, calleeMethod, null,
+                            "Called explicitly from a unit test.", "Test case");
             canonicalizer.applyIncremental(callerGraph, context, canonicalizeNodes);
             callerGraph.getDebug().dump(DebugContext.DETAILED_LEVEL, callerGraph, "After inlining %s into %s iteration %d", calleeMethod, callerMethod, i);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationPrinter.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationPrinter.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,10 +23,11 @@
 package org.graalvm.compiler.core;
 
 import static org.graalvm.compiler.core.GraalCompilerOptions.PrintCompilation;
+import static org.graalvm.compiler.serviceprovider.GraalServices.getCurrentThreadAllocatedBytes;
+import static org.graalvm.compiler.serviceprovider.GraalServices.isThreadAllocatedMemorySupported;
 
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
-import org.graalvm.compiler.debug.Management;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.options.OptionValues;
 
@@ -58,11 +59,6 @@
      */
     public static CompilationPrinter begin(OptionValues options, CompilationIdentifier id, JavaMethod method, int entryBCI) {
         if (PrintCompilation.getValue(options) && !TTY.isSuppressed()) {
-            try {
-                Class.forName("java.lang.management.ManagementFactory");
-            } catch (ClassNotFoundException ex) {
-                throw new IllegalArgumentException("PrintCompilation option requires java.management module");
-            }
             return new CompilationPrinter(id, method, entryBCI);
         }
         return DISABLED;
@@ -83,9 +79,8 @@
         this.id = id;
         this.entryBCI = entryBCI;
 
-        final long threadId = Thread.currentThread().getId();
         start = System.nanoTime();
-        allocatedBytesBefore = getAllocatedBytes(threadId);
+        allocatedBytesBefore = isThreadAllocatedMemorySupported() ? getCurrentThreadAllocatedBytes() : -1;
     }
 
     private String getMethodDescription() {
@@ -101,24 +96,17 @@
      */
     public void finish(CompilationResult result) {
         if (id != null) {
-            final long threadId = Thread.currentThread().getId();
             final long stop = System.nanoTime();
             final long duration = (stop - start) / 1000000;
             final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1;
             final int bytecodeSize = result != null ? result.getBytecodeSize() : 0;
-            final long allocatedBytesAfter = getAllocatedBytes(threadId);
-            final long allocatedKBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
-
-            TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB %5dkB", duration, bytecodeSize, targetCodeSize, allocatedKBytes));
+            if (allocatedBytesBefore == -1) {
+                TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB", duration, bytecodeSize, targetCodeSize));
+            } else {
+                final long allocatedBytesAfter = getCurrentThreadAllocatedBytes();
+                final long allocatedKBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
+                TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB %5dkB", duration, bytecodeSize, targetCodeSize, allocatedKBytes));
+            }
         }
     }
-
-    static com.sun.management.ThreadMXBean threadMXBean;
-
-    static long getAllocatedBytes(long threadId) {
-        if (threadMXBean == null) {
-            threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
-        }
-        return threadMXBean.getThreadAllocatedBytes(threadId);
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Tue Apr 24 09:04:57 2018 -0700
@@ -122,8 +122,10 @@
      *
      * Subclasses can override this to choose a different action based on factors such as whether
      * {@code actionKey} has been explicitly set in {@code options} for example.
+     *
+     * @param cause the cause of the bailout or failure
      */
-    protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey) {
+    protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey, Throwable cause) {
         if (actionKey == CompilationFailureAction) {
             if (ExitVMOnException.getValue(options)) {
                 assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
@@ -175,7 +177,7 @@
                 actionKey = CompilationFailureAction;
                 causeType = "failure";
             }
-            ExceptionAction action = lookupAction(initialOptions, actionKey);
+            ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
 
             action = adjustAction(initialOptions, actionKey, action);
 
@@ -262,22 +264,34 @@
                                 DumpPath, dumpPath.getPath());
 
                 try (DebugContext retryDebug = createRetryDebugContext(retryOptions)) {
-                    return performCompilation(retryDebug);
+                    T res = performCompilation(retryDebug);
+                    maybeExitVM(action);
+                    return res;
                 } catch (Throwable ignore) {
                     // Failures during retry are silent
-                    return handleException(cause);
-                } finally {
-                    if (action == ExitVM) {
-                        synchronized (ExceptionAction.class) {
-                            TTY.println("Exiting VM after retry compilation of " + this);
-                            System.exit(-1);
-                        }
-                    }
+                    T res = handleException(cause);
+                    maybeExitVM(action);
+                    return res;
                 }
             }
         }
     }
 
+    private void maybeExitVM(ExceptionAction action) {
+        if (action == ExitVM) {
+            synchronized (ExceptionAction.class) {
+                try {
+                    // Give other compiler threads a chance to flush
+                    // error handling output.
+                    ExceptionAction.class.wait(2000);
+                } catch (InterruptedException e) {
+                }
+                TTY.println("Exiting VM after retry compilation of " + this);
+                System.exit(-1);
+            }
+        }
+    }
+
     /**
      * Adjusts {@code initialAction} if necessary based on
      * {@link GraalCompilerOptions#MaxCompilationProblemsPerAction}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,10 +25,12 @@
 import java.util.Collection;
 import java.util.List;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
 import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.core.common.RetryableBailoutException;
 import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder;
 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
@@ -188,8 +190,18 @@
      *             {@code graph.method()} or {@code graph.name}
      */
     private static void checkForRequestedCrash(StructuredGraph graph) {
-        String methodPattern = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
-        if (methodPattern != null) {
+        String value = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
+        if (value != null) {
+            boolean bailout = false;
+            boolean permanentBailout = false;
+            String methodPattern = value;
+            if (value.endsWith(":Bailout")) {
+                methodPattern = value.substring(0, value.length() - ":Bailout".length());
+                bailout = true;
+            } else if (value.endsWith(":PermanentBailout")) {
+                methodPattern = value.substring(0, value.length() - ":PermanentBailout".length());
+                permanentBailout = true;
+            }
             String crashLabel = null;
             if (graph.name != null && graph.name.contains(methodPattern)) {
                 crashLabel = graph.name;
@@ -204,6 +216,12 @@
                 }
             }
             if (crashLabel != null) {
+                if (permanentBailout) {
+                    throw new PermanentBailoutException("Forced crash after compiling " + crashLabel);
+                }
+                if (bailout) {
+                    throw new RetryableBailoutException("Forced crash after compiling " + crashLabel);
+                }
                 throw new RuntimeException("Forced crash after compiling " + crashLabel);
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,12 +38,14 @@
     public static final OptionKey<Boolean> PrintCompilation = new OptionKey<>(false);
     @Option(help = "Pattern for method(s) that will trigger an exception when compiled. " +
                    "This option exists to test handling compilation crashes gracefully. " +
-                   "See the MethodFilter option for the pattern syntax. ", type = OptionType.Debug)
+                   "See the MethodFilter option for the pattern syntax. A ':Bailout' " +
+                   "suffix will raise a bailout exception and a ':PermanentBailout' " +
+                   "suffix will raise a permanent bailout exception.", type = OptionType.Debug)
     public static final OptionKey<String> CrashAt = new OptionKey<>(null);
     @Option(help = "file:doc-files/CompilationBailoutActionHelp.txt", type = OptionType.User)
     public static final EnumOptionKey<ExceptionAction> CompilationBailoutAction = new EnumOptionKey<>(ExceptionAction.Silent);
     @Option(help = "Specifies the action to take when compilation fails with a bailout exception. " +
-                    "The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
+                   "The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
      public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
     @Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
                    "by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.util.Arrays;
 import java.util.Queue;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,8 +33,8 @@
 import java.util.Collection;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,8 +28,8 @@
 import java.util.Arrays;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
 import org.graalvm.compiler.core.match.MatchPattern.Result;
 import org.graalvm.compiler.debug.DebugContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchRuleRegistry.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchRuleRegistry.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,9 +27,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/CommunityCompilerConfiguration.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.phases;
+
+import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
+import org.graalvm.compiler.lir.phases.AllocationStage;
+import org.graalvm.compiler.lir.phases.LIRPhaseSuite;
+import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
+import org.graalvm.compiler.lir.phases.PostAllocationOptimizationStage;
+import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
+import org.graalvm.compiler.lir.phases.PreAllocationOptimizationStage;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.MidTierContext;
+
+/**
+ * The default configuration for the community edition of Graal.
+ */
+public class CommunityCompilerConfiguration implements CompilerConfiguration {
+
+    @Override
+    public PhaseSuite<HighTierContext> createHighTier(OptionValues options) {
+        return new HighTier(options);
+    }
+
+    @Override
+    public PhaseSuite<MidTierContext> createMidTier(OptionValues options) {
+        return new MidTier(options);
+    }
+
+    @Override
+    public PhaseSuite<LowTierContext> createLowTier(OptionValues options) {
+        return new LowTier(options);
+    }
+
+    @Override
+    public LIRPhaseSuite<PreAllocationOptimizationContext> createPreAllocationOptimizationStage(OptionValues options) {
+        return new PreAllocationOptimizationStage(options);
+    }
+
+    @Override
+    public LIRPhaseSuite<AllocationContext> createAllocationStage(OptionValues options) {
+        return new AllocationStage(options);
+    }
+
+    @Override
+    public LIRPhaseSuite<PostAllocationOptimizationContext> createPostAllocationOptimizationStage(OptionValues options) {
+        return new PostAllocationOptimizationStage(options);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/CoreCompilerConfiguration.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.core.phases;
-
-import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
-import org.graalvm.compiler.lir.phases.AllocationStage;
-import org.graalvm.compiler.lir.phases.LIRPhaseSuite;
-import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
-import org.graalvm.compiler.lir.phases.PostAllocationOptimizationStage;
-import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
-import org.graalvm.compiler.lir.phases.PreAllocationOptimizationStage;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.LowTierContext;
-import org.graalvm.compiler.phases.tiers.MidTierContext;
-
-public class CoreCompilerConfiguration implements CompilerConfiguration {
-
-    @Override
-    public PhaseSuite<HighTierContext> createHighTier(OptionValues options) {
-        return new HighTier(options);
-    }
-
-    @Override
-    public PhaseSuite<MidTierContext> createMidTier(OptionValues options) {
-        return new MidTier(options);
-    }
-
-    @Override
-    public PhaseSuite<LowTierContext> createLowTier(OptionValues options) {
-        return new LowTier(options);
-    }
-
-    @Override
-    public LIRPhaseSuite<PreAllocationOptimizationContext> createPreAllocationOptimizationStage(OptionValues options) {
-        return new PreAllocationOptimizationStage(options);
-    }
-
-    @Override
-    public LIRPhaseSuite<AllocationContext> createAllocationStage(OptionValues options) {
-        return new AllocationStage(options);
-    }
-
-    @Override
-    public LIRPhaseSuite<PostAllocationOptimizationContext> createPostAllocationOptimizationStage(OptionValues options) {
-        return new PostAllocationOptimizationStage(options);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyCompilerConfiguration.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyCompilerConfiguration.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,6 +36,10 @@
 import org.graalvm.compiler.phases.tiers.LowTierContext;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
 
+/**
+ * A compiler configuration that performs fewer Graal IR optimizations while using the same backend
+ * as the {@link CommunityCompilerConfiguration}.
+ */
 public class EconomyCompilerConfiguration implements CompilerConfiguration {
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.core.phases;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Graph.NodeEvent;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.ArrayList;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.GraphSpeculationLog;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.phases.tiers.SuitesProvider;
 import org.graalvm.compiler.phases.tiers.TargetProvider;
@@ -209,7 +210,7 @@
             try {
                 preCodeInstallationTasks(tasks, compilationResult, predefinedInstalledCode);
                 CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
-                installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
+                installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, GraphSpeculationLog.unwrap(speculationLog), isDefault);
                 assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
             } catch (Throwable t) {
                 failCodeInstallationTasks(tasks, t);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import java.util.Formatter;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,16 +28,14 @@
 import static org.graalvm.compiler.debug.DebugContext.NO_GLOBAL_METRIC_VALUES;
 import static org.junit.Assert.assertEquals;
 
-import java.lang.management.ThreadMXBean;
-
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.debug.Management;
 import org.graalvm.compiler.debug.TimerKey;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
@@ -47,12 +45,7 @@
 
     @Before
     public void checkCapabilities() {
-        try {
-            ThreadMXBean threadMXBean = Management.getThreadMXBean();
-            Assume.assumeTrue("skipping management interface test", threadMXBean.isCurrentThreadCpuTimeSupported());
-        } catch (LinkageError err) {
-            Assume.assumeNoException("Cannot run without java.management JDK9 module", err);
-        }
+        Assume.assumeTrue("skipping management interface test", GraalServices.isCurrentThreadCpuTimeSupported());
     }
 
     /**
@@ -63,10 +56,9 @@
      *         {@code ms}
      */
     private static long spin(long ms) {
-        ThreadMXBean threadMXBean = Management.getThreadMXBean();
-        long start = threadMXBean.getCurrentThreadCpuTime();
+        long start = GraalServices.getCurrentThreadCpuTime();
         do {
-            long durationMS = (threadMXBean.getCurrentThreadCpuTime() - start) / 1000;
+            long durationMS = (GraalServices.getCurrentThreadCpuTime() - start) / 1000;
             if (durationMS >= ms) {
                 return durationMS;
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CounterKeyImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CounterKeyImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.debug;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 
 class CounterKeyImpl extends AbstractKey implements CounterKey {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugConfigImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugConfigImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -264,9 +264,8 @@
                     firstSeen.put(o, o);
                     if (DebugOptions.DumpOnError.getValue(options) || DebugOptions.Dump.getValue(options) != null) {
                         debug.dump(DebugContext.BASIC_LEVEL, o, "Exception: %s", e);
-                    } else {
-                        debug.log("Context obj %s", o);
                     }
+                    debug.log("Context obj %s", o);
                 }
             }
         } finally {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Tue Apr 24 09:04:57 2018 -0700
@@ -56,11 +56,12 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.graalvm.graphio.GraphOutput;
 
 import jdk.vm.ci.meta.JavaMethod;
@@ -236,14 +237,15 @@
             this.unscopedTimers = parseUnscopedMetricSpec(Timers.getValue(options), "".equals(timeValue), true);
             this.unscopedMemUseTrackers = parseUnscopedMetricSpec(MemUseTrackers.getValue(options), "".equals(trackMemUseValue), true);
 
-            if (unscopedTimers != null ||
-                            unscopedMemUseTrackers != null ||
-                            timeValue != null ||
-                            trackMemUseValue != null) {
-                try {
-                    Class.forName("java.lang.management.ManagementFactory");
-                } catch (ClassNotFoundException ex) {
-                    throw new IllegalArgumentException("Time, Timers, MemUseTrackers and TrackMemUse options require java.management module");
+            if (unscopedTimers != null || timeValue != null) {
+                if (!GraalServices.isCurrentThreadCpuTimeSupported()) {
+                    throw new IllegalArgumentException("Time and Timers options require VM support for querying CPU time");
+                }
+            }
+
+            if (unscopedMemUseTrackers != null || trackMemUseValue != null) {
+                if (!GraalServices.isThreadAllocatedMemorySupported()) {
+                    throw new IllegalArgumentException("MemUseTrackers and TrackMemUse options require VM support for querying thread allocated memory");
                 }
             }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,11 +27,12 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 /**
  * Options that configure a {@link DebugContext} and related functionality.
@@ -133,9 +134,7 @@
 
     @Option(help = "Host part of the address to which graphs are dumped.", type = OptionType.Debug)
     public static final OptionKey<String> PrintGraphHost = new OptionKey<>("127.0.0.1");
-    @Option(help = "Port part of the address to which graphs are dumped in XML format (ignored if PrintBinaryGraphs=true).", type = OptionType.Debug)
-    public static final OptionKey<Integer> PrintXmlGraphPort = new OptionKey<>(4444);
-    @Option(help = "Port part of the address to which graphs are dumped in binary format (ignored if PrintBinaryGraphs=false).", type = OptionType.Debug)
+    @Option(help = "Port part of the address to which graphs are dumped in binary format.", type = OptionType.Debug)
     public static final OptionKey<Integer> PrintBinaryGraphPort = new OptionKey<>(4445);
     @Option(help = "Schedule graphs as they are dumped.", type = OptionType.Debug)
     public static final OptionKey<Boolean> PrintGraphWithSchedule = new OptionKey<>(false);
@@ -164,23 +163,10 @@
     @Option(help = "Do not compile anything on bootstrap but just initialize the compiler.", type = OptionType.Debug)
     public static final OptionKey<Boolean> BootstrapInitializeOnly = new OptionKey<>(false);
 
-    // These will be removed at some point
-    @Option(help = "Deprecated - use PrintGraphHost instead.", type = OptionType.Debug)
-    static final OptionKey<String> PrintIdealGraphAddress = new DebugOptions.DeprecatedOptionKey<>(PrintGraphHost);
-    @Option(help = "Deprecated - use PrintGraphWithSchedule instead.", type = OptionType.Debug)
-    static final OptionKey<Boolean> PrintIdealGraphSchedule = new DebugOptions.DeprecatedOptionKey<>(PrintGraphWithSchedule);
-    @Option(help = "Deprecated - use PrintGraph instead.", type = OptionType.Debug)
-    static final OptionKey<Boolean> PrintIdealGraph = new DebugOptions.DeprecatedOptionKey<>(PrintGraph);
-    @Option(help = "Deprecated - use PrintGraphFile instead.", type = OptionType.Debug)
-    static final OptionKey<Boolean> PrintIdealGraphFile = new DebugOptions.DeprecatedOptionKey<>(PrintGraphFile);
-    @Option(help = "Deprecated - use PrintXmlGraphPort instead.", type = OptionType.Debug)
-    static final OptionKey<Integer> PrintIdealGraphPort = new DebugOptions.DeprecatedOptionKey<>(PrintXmlGraphPort);
-    // @formatter:on
-
     /**
      * Gets the directory in which {@link DebugDumpHandler}s can generate output. This will be the
      * directory specified by {@link #DumpPath} if it has been set otherwise it will be derived from
-     * the default value of {@link #DumpPath} and {@link PathUtilities#getGlobalTimeStamp()}.
+     * the default value of {@link #DumpPath} and {@link GraalServices#getGlobalTimeStamp()}.
      *
      * This method will ensure the returned directory exists, printing a message to {@link TTY} if
      * it creates it.
@@ -193,14 +179,16 @@
         if (DumpPath.hasBeenSet(options)) {
             dumpDir = Paths.get(DumpPath.getValue(options));
         } else {
-            dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(PathUtilities.getGlobalTimeStamp()));
+            dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(GraalServices.getGlobalTimeStamp()));
         }
         dumpDir = dumpDir.toAbsolutePath();
         if (!Files.exists(dumpDir)) {
             synchronized (DebugConfigImpl.class) {
                 if (!Files.exists(dumpDir)) {
                     Files.createDirectories(dumpDir);
-                    TTY.println("Dumping debug output in %s", dumpDir.toString());
+                    if (ShowDumpFiles.getValue(options)) {
+                        TTY.println("Dumping debug output in %s", dumpDir.toString());
+                    }
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,6 +39,7 @@
 import java.util.zip.ZipOutputStream;
 
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 /**
  * Manages a directory into which diagnostics such crash reports and dumps should be written. The
@@ -69,26 +70,6 @@
         return getPath(true);
     }
 
-    /**
-     * Gets a unique identifier for this execution such as a process ID.
-     */
-    protected String getExecutionID() {
-        try {
-            String runtimeName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
-            try {
-                int index = runtimeName.indexOf('@');
-                if (index != -1) {
-                    long pid = Long.parseLong(runtimeName.substring(0, index));
-                    return Long.toString(pid);
-                }
-            } catch (NumberFormatException e) {
-            }
-            return runtimeName;
-        } catch (LinkageError err) {
-            return String.valueOf(org.graalvm.compiler.debug.PathUtilities.getGlobalTimeStamp());
-        }
-    }
-
     private synchronized String getPath(boolean createIfNull) {
         if (path == null && createIfNull) {
             path = createPath();
@@ -120,7 +101,7 @@
             // directory specified by the DumpPath option.
             baseDir = Paths.get(".");
         }
-        return baseDir.resolve("graal_diagnostics_" + getExecutionID()).toAbsolutePath().toString();
+        return baseDir.resolve("graal_diagnostics_" + GraalServices.getExecutionID()).toAbsolutePath().toString();
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,9 +29,9 @@
 import java.util.Collections;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.options.OptionValues;
 
 /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/KeyRegistry.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/KeyRegistry.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 
 /**
  * Registry for allocating a globally unique integer id to each {@link AbstractKey}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Management.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.debug;
-
-import static java.lang.Thread.currentThread;
-
-public class Management {
-
-    private static final com.sun.management.ThreadMXBean threadMXBean = Management.initThreadMXBean();
-
-    /**
-     * The amount of memory allocated by
-     * {@link com.sun.management.ThreadMXBean#getThreadAllocatedBytes(long)} itself.
-     */
-    private static final long threadMXBeanOverhead = -getCurrentThreadAllocatedBytes() + getCurrentThreadAllocatedBytes();
-
-    public static long getCurrentThreadAllocatedBytes() {
-        return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead;
-    }
-
-    private static com.sun.management.ThreadMXBean initThreadMXBean() {
-        try {
-            return (com.sun.management.ThreadMXBean) java.lang.management.ManagementFactory.getThreadMXBean();
-        } catch (Error err) {
-            return new UnimplementedBean();
-        }
-    }
-
-    public static java.lang.management.ThreadMXBean getThreadMXBean() {
-        return threadMXBean;
-    }
-
-    private static class UnimplementedBean implements java.lang.management.ThreadMXBean, com.sun.management.ThreadMXBean {
-
-        @Override
-        public javax.management.ObjectName getObjectName() {
-            return null;
-        }
-
-        @Override
-        public long getThreadAllocatedBytes(long arg0) {
-            return 0;
-        }
-
-        @Override
-        public long[] getThreadAllocatedBytes(long[] arg0) {
-            return null;
-        }
-
-        @Override
-        public long[] getThreadCpuTime(long[] arg0) {
-            return null;
-        }
-
-        @Override
-        public long[] getThreadUserTime(long[] arg0) {
-            return null;
-        }
-
-        @Override
-        public boolean isThreadAllocatedMemoryEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isThreadAllocatedMemorySupported() {
-            return false;
-        }
-
-        @Override
-        public void setThreadAllocatedMemoryEnabled(boolean arg0) {
-        }
-
-        @Override
-        public int getThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public int getPeakThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public long getTotalStartedThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public int getDaemonThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public long[] getAllThreadIds() {
-            return null;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo getThreadInfo(long id) {
-            return null;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids) {
-            return null;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo getThreadInfo(long id, int maxDepth) {
-            return null;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
-            return null;
-        }
-
-        @Override
-        public boolean isThreadContentionMonitoringSupported() {
-            return false;
-        }
-
-        @Override
-        public boolean isThreadContentionMonitoringEnabled() {
-            return false;
-        }
-
-        @Override
-        public void setThreadContentionMonitoringEnabled(boolean enable) {
-        }
-
-        @Override
-        public long getCurrentThreadCpuTime() {
-            return 0;
-        }
-
-        @Override
-        public long getCurrentThreadUserTime() {
-            return 0;
-        }
-
-        @Override
-        public long getThreadCpuTime(long id) {
-            return 0;
-        }
-
-        @Override
-        public long getThreadUserTime(long id) {
-            return 0;
-        }
-
-        @Override
-        public boolean isThreadCpuTimeSupported() {
-            return false;
-        }
-
-        @Override
-        public boolean isCurrentThreadCpuTimeSupported() {
-            return false;
-        }
-
-        @Override
-        public boolean isThreadCpuTimeEnabled() {
-            return false;
-        }
-
-        @Override
-        public void setThreadCpuTimeEnabled(boolean enable) {
-        }
-
-        @Override
-        public long[] findMonitorDeadlockedThreads() {
-            return null;
-        }
-
-        @Override
-        public void resetPeakThreadCount() {
-        }
-
-        @Override
-        public long[] findDeadlockedThreads() {
-            return null;
-        }
-
-        @Override
-        public boolean isObjectMonitorUsageSupported() {
-            return false;
-        }
-
-        @Override
-        public boolean isSynchronizerUsageSupported() {
-            return false;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers) {
-            return null;
-        }
-
-        @Override
-        public java.lang.management.ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) {
-            return null;
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.debug;
 
+import org.graalvm.compiler.serviceprovider.GraalServices;
+
 /**
  * Tracks memory usage within a scope using {@link com.sun.management.ThreadMXBean}. This facility
  * should be employed using the try-with-resources pattern:
@@ -52,6 +54,6 @@
     MemUseTrackerKey doc(String string);
 
     static long getCurrentThreadAllocatedBytes() {
-        return Management.getCurrentThreadAllocatedBytes();
+        return GraalServices.getCurrentThreadAllocatedBytes();
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKeyImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKeyImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 
 class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MetricKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MetricKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.Comparator;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 
 /**
  * A key for a metric.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,6 @@
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.concurrent.atomic.AtomicLong;
 
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
@@ -39,19 +38,6 @@
  */
 public class PathUtilities {
 
-    private static final AtomicLong globalTimeStamp = new AtomicLong();
-
-    /**
-     * Gets a time stamp for the current process. This method will always return the same value for
-     * the current VM execution.
-     */
-    public static long getGlobalTimeStamp() {
-        if (globalTimeStamp.get() == 0) {
-            globalTimeStamp.compareAndSet(0, System.currentTimeMillis());
-        }
-        return globalTimeStamp.get();
-    }
-
     /**
      * Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
      * without causing an {@link InvalidPathException}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimeSource.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimeSource.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,21 +22,13 @@
  */
 package org.graalvm.compiler.debug;
 
+import org.graalvm.compiler.serviceprovider.GraalServices;
+
 /**
  * A consistent source of timing data that should be used by all facilities in the debug package.
  */
 public class TimeSource {
-    private static final boolean USING_BEAN;
-    private static final java.lang.management.ThreadMXBean threadMXBean;
-
-    static {
-        threadMXBean = Management.getThreadMXBean();
-        if (threadMXBean.isThreadCpuTimeSupported()) {
-            USING_BEAN = true;
-        } else {
-            USING_BEAN = false;
-        }
-    }
+    private static final boolean USING_THREAD_CPU_TIME = GraalServices.isCurrentThreadCpuTimeSupported();
 
     /**
      * Gets the current time of this thread in nanoseconds from the most accurate timer available on
@@ -50,7 +42,7 @@
      * @return the current thread's time in nanoseconds
      */
     public static long getTimeNS() {
-        return USING_BEAN ? threadMXBean.getCurrentThreadCpuTime() : System.nanoTime();
+        return USING_THREAD_CPU_TIME ? GraalServices.getCurrentThreadCpuTime() : System.nanoTime();
     }
 
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 
 import java.util.concurrent.TimeUnit;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 
 final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
     static class FlatTimer extends AbstractKey implements TimerKey {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/.checkstyle_checks.xml	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +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: Checks
-    Description: none
--->
-<module name="Checker">
-  <property name="severity" value="error"/>
-  <module name="TreeWalker">
-    <module name="AvoidStarImport">
-      <property name="allowClassImports" value="false"/>
-      <property name="allowStaticMemberImports" value="false"/>
-    </module>
-    <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"/>
-    <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="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="false"/>
-      <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.comment" value="Checks for whitespace before a comma."/>
-      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="[^\x00-\x7F]"/>
-      <property name="message" value="Only use ASCII characters."/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
-      <property name="message" value="Don't use old synchronized collection classes"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof MoveOp"/>
-      <property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof ValueMoveOp"/>
-      <property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof LoadConstantOp"/>
-      <property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(MoveOp\)"/>
-      <property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(ValueMoveOp\)"/>
-      <property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(LoadConstantOp\)"/>
-      <property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
-    </module>
-  </module>
-  <module name="RegexpHeader">
-    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates\. All rights reserved\.\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], .*\. All rights reserved\.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER\.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation\.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE\.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\)\.\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc\., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www\.oracle\.com if you need additional information or have any\n \* questions\.\n \*/\n"/>
-    <property name="multiLines" value="3"/>
-    <property name="fileExtensions" value="java"/>
-  </module>
-  <module name="FileTabCharacter">
-    <property name="severity" value="error"/>
-    <property name="fileExtensions" value="java"/>
-  </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="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 name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
-    <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
-    <property name="checkFormat" value="LineLength"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: start generated"/>
-    <property name="onCommentFormat" value="CheckStyle: stop generated"/>
-    <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
-  </module>
-</module>
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/CachedGraph.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/CachedGraph.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.function.Consumer;
 
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 
 /**
  * This class is a container of a graph that needs to be readonly and optionally a lazily created
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.graph;
 
+import static org.graalvm.compiler.core.common.GraalOptions.TrackNodeInsertion;
 import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Default;
 import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Track;
 import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.UpdateOnly;
@@ -33,15 +34,16 @@
 import java.util.Iterator;
 import java.util.function.Consumer;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.TimerKey;
+import org.graalvm.compiler.graph.Node.NodeInsertionStackTrace;
 import org.graalvm.compiler.graph.Node.ValueNumberable;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.options.Option;
@@ -49,6 +51,8 @@
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 /**
  * This class is a graph container, it contains the set of nodes that belong to this graph.
  */
@@ -195,7 +199,7 @@
      *         was opened
      */
     public DebugCloseable withNodeSourcePosition(Node node) {
-        return withNodeSourcePosition(node.sourcePosition);
+        return withNodeSourcePosition(node.getNodeSourcePosition());
     }
 
     /**
@@ -719,6 +723,9 @@
         assert node.getNodeClass().valueNumberable();
         T other = this.findDuplicate(node);
         if (other != null) {
+            if (other.getNodeSourcePosition() == null) {
+                other.setNodeSourcePosition(node.getNodeSourcePosition());
+            }
             return other;
         } else {
             T result = addHelper(node);
@@ -1097,6 +1104,9 @@
         if (currentNodeSourcePosition != null && trackNodeSourcePosition()) {
             node.setNodeSourcePosition(currentNodeSourcePosition);
         }
+        if (TrackNodeInsertion.getValue(getOptions())) {
+            node.setInsertionPosition(new NodeInsertionStackTrace());
+        }
 
         updateNodeCaches(node);
 
@@ -1189,6 +1199,23 @@
         return true;
     }
 
+    public boolean verifySourcePositions() {
+        if (trackNodeSourcePosition()) {
+            ResolvedJavaMethod root = null;
+            for (Node node : getNodes()) {
+                NodeSourcePosition pos = node.getNodeSourcePosition();
+                if (pos != null) {
+                    if (root == null) {
+                        root = pos.getRootMethod();
+                    } else {
+                        assert pos.verifyRootMethod(root) : node;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
     public Node getNode(int id) {
         return nodes[id];
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,6 +29,7 @@
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Formattable;
@@ -84,7 +85,8 @@
 public abstract class Node implements Cloneable, Formattable, NodeInterface {
 
     public static final NodeClass<?> TYPE = null;
-    public static final boolean USE_UNSAFE_TO_CLONE = true;
+
+    public static final boolean TRACK_CREATION_POSITION = Boolean.getBoolean("debug.graal.TrackNodeCreationPosition");
 
     static final int DELETED_ID_START = -1000000000;
     static final int INITIAL_ID = -1;
@@ -230,6 +232,40 @@
     public static final int NODE_LIST = -2;
     public static final int NOT_ITERABLE = -1;
 
+    static class NodeStackTrace {
+        final StackTraceElement[] stackTrace;
+
+        NodeStackTrace() {
+            this.stackTrace = new Throwable().getStackTrace();
+        }
+
+        private String getString(String label) {
+            StringBuilder sb = new StringBuilder();
+            if (label != null) {
+                sb.append(label).append(": ");
+            }
+            for (StackTraceElement ste : stackTrace) {
+                sb.append("at ").append(ste.toString()).append('\n');
+            }
+            return sb.toString();
+        }
+
+        String getStrackTraceString() {
+            return getString(null);
+        }
+
+        @Override
+        public String toString() {
+            return getString(getClass().getSimpleName());
+        }
+    }
+
+    static class NodeCreationStackTrace extends NodeStackTrace {
+    }
+
+    static class NodeInsertionStackTrace extends NodeStackTrace {
+    }
+
     public Node(NodeClass<? extends Node> c) {
         init(c);
     }
@@ -239,6 +275,9 @@
         this.nodeClass = c;
         id = INITIAL_ID;
         extraUsages = NO_NODES;
+        if (TRACK_CREATION_POSITION) {
+            setCreationPosition(new NodeCreationStackTrace());
+        }
     }
 
     final int id() {
@@ -577,32 +616,95 @@
     }
 
     /**
-     * The position of the bytecode that generated this node.
+     * Information associated with this node. A single value is stored directly in the field.
+     * Multiple values are stored by creating an Object[].
      */
-    NodeSourcePosition sourcePosition;
+    private Object annotation;
+
+    private <T> T getNodeInfo(Class<T> clazz) {
+        assert clazz != Object[].class;
+        if (annotation == null) {
+            return null;
+        }
+        if (clazz.isInstance(annotation)) {
+            return clazz.cast(annotation);
+        }
+        if (annotation.getClass() == Object[].class) {
+            Object[] annotations = (Object[]) annotation;
+            for (Object ann : annotations) {
+                if (clazz.isInstance(ann)) {
+                    return clazz.cast(ann);
+                }
+            }
+        }
+        return null;
+    }
+
+    private <T> void setNodeInfo(Class<T> clazz, T value) {
+        assert clazz != Object[].class;
+        if (annotation == null || clazz.isInstance(annotation)) {
+            // Replace the current value
+            this.annotation = value;
+        } else if (annotation.getClass() == Object[].class) {
+            Object[] annotations = (Object[]) annotation;
+            for (int i = 0; i < annotations.length; i++) {
+                if (clazz.isInstance(annotations[i])) {
+                    annotations[i] = value;
+                    return;
+                }
+            }
+            Object[] newAnnotations = Arrays.copyOf(annotations, annotations.length + 1);
+            newAnnotations[annotations.length] = value;
+            this.annotation = newAnnotations;
+        } else {
+            this.annotation = new Object[]{this.annotation, value};
+        }
+    }
 
     /**
      * Gets the source position information for this node or null if it doesn't exist.
      */
 
     public NodeSourcePosition getNodeSourcePosition() {
-        return sourcePosition;
+        return getNodeInfo(NodeSourcePosition.class);
     }
 
     /**
-     * Set the source position to {@code sourcePosition}.
+     * Set the source position to {@code sourcePosition}. Setting it to null is ignored so that it's
+     * not accidentally cleared. Use {@link #clearNodeSourcePosition()} instead.
      */
     public void setNodeSourcePosition(NodeSourcePosition sourcePosition) {
-        assert sourcePosition != null || this.sourcePosition == null || this.sourcePosition.isPlaceholder() : "Invalid source position at node with id " + id;
-        this.sourcePosition = sourcePosition;
-        // assert sourcePosition == null || graph == null || graph.trackNodeSourcePosition;
+        if (sourcePosition == null) {
+            return;
+        }
+        setNodeInfo(NodeSourcePosition.class, sourcePosition);
+    }
+
+    public void clearNodeSourcePosition() {
+        setNodeInfo(NodeSourcePosition.class, null);
+    }
+
+    public NodeCreationStackTrace getCreationPosition() {
+        return getNodeInfo(NodeCreationStackTrace.class);
+    }
+
+    public void setCreationPosition(NodeCreationStackTrace trace) {
+        setNodeInfo(NodeCreationStackTrace.class, trace);
+    }
+
+    public NodeInsertionStackTrace getInsertionPosition() {
+        return getNodeInfo(NodeInsertionStackTrace.class);
+    }
+
+    public void setInsertionPosition(NodeInsertionStackTrace trace) {
+        setNodeInfo(NodeInsertionStackTrace.class, trace);
     }
 
     /**
      * Update the source position only if it is null.
      */
     public void updateNodeSourcePosition(Supplier<NodeSourcePosition> sourcePositionSupp) {
-        if (this.sourcePosition == null) {
+        if (this.getNodeSourcePosition() == null) {
             setNodeSourcePosition(sourcePositionSupp.get());
         }
     }
@@ -919,8 +1021,8 @@
         }
         newNode.graph = into;
         newNode.id = INITIAL_ID;
-        if (sourcePosition != null && (into == null || into.updateNodeSourcePosition())) {
-            newNode.setNodeSourcePosition(sourcePosition);
+        if (getNodeSourcePosition() != null && (into == null || into.updateNodeSourcePosition())) {
+            newNode.setNodeSourcePosition(getNodeSourcePosition());
         }
         if (into != null) {
             into.register(newNode);
@@ -1077,6 +1179,14 @@
         if (pos != null) {
             map.put("nodeSourcePosition", pos);
         }
+        NodeCreationStackTrace creation = getCreationPosition();
+        if (creation != null) {
+            map.put("nodeCreationPosition", creation.getStrackTraceString());
+        }
+        NodeInsertionStackTrace insertion = getInsertionPosition();
+        if (insertion != null) {
+            map.put("nodeInsertionPosition", insertion.getStrackTraceString());
+        }
         return map;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,8 +42,8 @@
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.FieldIntrospection;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.core.common.FieldsScanner;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.util.Iterator;
 import java.util.function.BiFunction;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
 
 public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java	Tue Apr 24 09:04:57 2018 -0700
@@ -64,6 +64,21 @@
         return this;
     }
 
+    public ResolvedJavaMethod getRootMethod() {
+        NodeSourcePosition cur = this;
+        while (cur.getCaller() != null) {
+            cur = cur.getCaller();
+        }
+        return cur.getMethod();
+    }
+
+    public boolean verifyRootMethod(ResolvedJavaMethod root) {
+        JavaMethod currentRoot = getRootMethod();
+        assert root.equals(currentRoot) || root.getName().equals(currentRoot.getName()) && root.getSignature().toMethodDescriptor().equals(currentRoot.getSignature().toMethodDescriptor()) &&
+                        root.getDeclaringClass().getName().equals(currentRoot.getDeclaringClass().getName()) : root + " " + currentRoot;
+        return true;
+    }
+
     enum Marker {
         None,
         Placeholder,
@@ -107,11 +122,11 @@
     }
 
     public static NodeSourcePosition substitution(ResolvedJavaMethod method) {
-        return new NodeSourcePosition(null, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Substitution);
+        return substitution(null, method);
     }
 
-    public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
-        return new NodeSourcePosition(caller, method, bci, Substitution);
+    public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method) {
+        return new NodeSourcePosition(caller, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Substitution);
     }
 
     public boolean isSubstitution() {
@@ -151,7 +166,7 @@
         return d;
     }
 
-    public SourceLanguagePosition getSourceLanauage() {
+    public SourceLanguagePosition getSourceLanguage() {
         return sourceLanguagePosition;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.graph;
 
-import java.util.Map;
+import java.net.URI;
 
 /**
  * Provides a path to report information about a high level language source position to the Graph
@@ -31,14 +31,22 @@
 public interface SourceLanguagePosition {
 
     /**
-     * This is called during dumping of Nodes. The implementation should add any properties which
-     * describe this source position. The actual keys and values used are a private contract between
-     * the language implementation and the Graph Visualizer.
-     */
-    void addSourceInformation(Map<String, Object> props);
-
-    /**
      * Produce a compact description of this position suitable for printing.
      */
     String toShortString();
+
+    /** Mimics GraphLocations operation. */
+    int getOffsetEnd();
+
+    /** Mimics GraphLocations operation. */
+    int getOffsetStart();
+
+    /** Mimics GraphLocations operation. */
+    int getLineNumber();
+
+    /** Mimics GraphLocations operation. */
+    URI getURI();
+
+    /** Mimics GraphLocations operation. */
+    String getLanguage();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,7 +31,7 @@
 import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
 import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
+import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
@@ -50,7 +51,11 @@
 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
+import org.graalvm.compiler.nodes.spi.Replacements;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.Phase;
+import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
+import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.aarch64.AArch64GraphBuilderPlugins;
@@ -77,7 +82,7 @@
 
     @Override
     public String getName() {
-        return "core";
+        return "community";
     }
 
     @Override
@@ -141,7 +146,7 @@
                 replacements.setGraphBuilderPlugins(plugins);
             }
             try (InitTimer rt = timer("create Suites provider")) {
-                suites = createSuites(config, graalRuntime, compilerConfiguration, plugins);
+                suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements);
             }
             providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
                             snippetReflection, wordTypes,
@@ -178,8 +183,11 @@
         return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
     }
 
-    protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins) {
-        return new AArch64HotSpotSuitesProvider(new AArch64SuitesCreator(compilerConfiguration, plugins), config, runtime, new AArch64AddressLoweringByUse(new AArch64LIRKindTool()));
+    protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
+                    @SuppressWarnings("unused") Replacements replacements) {
+        AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, SchedulePhase.class);
+        Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool()));
+        return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase);
     }
 
     protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,7 +31,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
 import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
 import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.AllocatableValue;
@@ -68,11 +69,12 @@
     public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
         leaveFrame(crb, masm, /* emitSafepoint */false);
 
-        if (System.getProperty("java.specification.version").compareTo("1.8") < 0) {
+        if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) {
             // Restore sp from fp if the exception PC is a method handle call site.
             try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
-                AArch64Address address = masm.makeAddress(thread, isMethodHandleReturnOffset, scratch, 4, /* allowOverwrite */false);
+                final boolean allowOverwrite = false;
+                AArch64Address address = masm.makeAddress(thread, isMethodHandleReturnOffset, scratch, 4, allowOverwrite);
                 masm.ldr(32, scratch, address);
                 Label noRestore = new Label();
                 masm.cbz(32, scratch, noRestore);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,7 +42,6 @@
 import static jdk.vm.ci.aarch64.AArch64.r24;
 import static jdk.vm.ci.aarch64.AArch64.r25;
 import static jdk.vm.ci.aarch64.AArch64.r26;
-import static jdk.vm.ci.aarch64.AArch64.r27;
 import static jdk.vm.ci.aarch64.AArch64.r28;
 import static jdk.vm.ci.aarch64.AArch64.r3;
 import static jdk.vm.ci.aarch64.AArch64.r4;
@@ -100,7 +99,7 @@
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
         r8,  r9,  r10, r11, r12, r13, r14, r15,
         r16, r17, r18, r19, r20, r21, r22, r23,
-        r24, r25, r26, r27, r28, /* r29, r30, r31 */
+        r24, r25, r26, /* r27, */ r28, /* r29, r30, r31 */
 
         v0,  v1,  v2,  v3,  v4,  v5,  v6,  v7,
         v8,  v9,  v10, v11, v12, v13, v14, v15,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSuitesProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.aarch64;
-
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
-import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
-import org.graalvm.compiler.phases.common.ExpandLogicPhase;
-import org.graalvm.compiler.phases.common.FixReadsPhase;
-import org.graalvm.compiler.phases.common.PropagateDeoptimizeProbabilityPhase;
-import org.graalvm.compiler.phases.tiers.LowTierContext;
-import org.graalvm.compiler.phases.tiers.Suites;
-import org.graalvm.compiler.phases.tiers.SuitesCreator;
-import org.graalvm.compiler.replacements.aarch64.AArch64ReadReplacementPhase;
-
-import java.util.ListIterator;
-
-/**
- * Subclass to factor out management of address lowering.
- */
-public class AArch64HotSpotSuitesProvider extends HotSpotSuitesProvider {
-
-    private final AddressLoweringByUsePhase.AddressLoweringByUse addressLoweringByUse;
-
-    public AArch64HotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime,
-                    AddressLoweringByUsePhase.AddressLoweringByUse addressLoweringByUse) {
-        super(defaultSuitesCreator, config, runtime);
-        this.addressLoweringByUse = addressLoweringByUse;
-    }
-
-    @Override
-    public Suites createSuites(OptionValues options) {
-        Suites suites = super.createSuites(options);
-
-        ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(FixReadsPhase.class);
-        if (findPhase == null) {
-            findPhase = suites.getLowTier().findPhase(ExpandLogicPhase.class);
-        }
-        findPhase.add(new AddressLoweringByUsePhase(addressLoweringByUse));
-
-        findPhase = suites.getLowTier().findPhase(PropagateDeoptimizeProbabilityPhase.class);
-        findPhase.add(new AArch64ReadReplacementPhase());
-
-        return suites;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.amd64.AMD64AddressNode;
 import org.graalvm.compiler.core.amd64.AMD64CompressAddressLowering;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,7 +30,7 @@
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -52,6 +52,7 @@
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.Replacements;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.common.AddressLoweringPhase;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.amd64.AMD64GraphBuilderPlugins;
@@ -77,7 +78,7 @@
 
     @Override
     public String getName() {
-        return "core";
+        return "community";
     }
 
     @Override
@@ -186,7 +187,7 @@
     protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
                     HotSpotRegistersProvider registers, Replacements replacements, OptionValues options) {
         return new AddressLoweringHotSpotSuitesProvider(new AMD64HotSpotSuitesCreator(compilerConfiguration, plugins), config, runtime,
-                        new AMD64HotSpotAddressLowering(config, registers.getHeapBaseRegister(), options));
+                        new AddressLoweringPhase(new AMD64HotSpotAddressLowering(config, registers.getHeapBaseRegister(), options)));
     }
 
     protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP;
 import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
 import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.AllocatableValue;
@@ -68,7 +69,7 @@
         // Discard the return address, thus completing restoration of caller frame
         masm.incrementq(rsp, 8);
 
-        if (System.getProperty("java.specification.version").compareTo("1.8") < 0) {
+        if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) {
             // Restore rsp from rbp if the exception PC is a method handle call site.
             AMD64Address dst = new AMD64Address(thread, isMethodHandleReturnOffset);
             masm.cmpl(dst, 0);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java	Tue Apr 24 09:04:57 2018 -0700
@@ -46,9 +46,9 @@
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.sparc.SPARCAddress;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.Replacements;
+import org.graalvm.compiler.phases.common.AddressLoweringPhase;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
@@ -72,7 +73,7 @@
 
     @Override
     public String getName() {
-        return "core";
+        return "community";
     }
 
     @Override
@@ -125,7 +126,7 @@
      */
     protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
                     Replacements replacements) {
-        return new AddressLoweringHotSpotSuitesProvider(new SPARCSuitesCreator(compilerConfiguration, plugins), config, runtime, new SPARCAddressLowering());
+        return new AddressLoweringHotSpotSuitesProvider(new SPARCSuitesCreator(compilerConfiguration, plugins), config, runtime, new AddressLoweringPhase(new SPARCAddressLowering()));
     }
 
     protected SPARCHotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,7 +35,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP;
 import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
 import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,8 +32,8 @@
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@@ -43,7 +43,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
 import org.graalvm.compiler.runtime.RuntimeProvider;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.graalvm.compiler.test.GraalTest;
 import org.junit.Test;
 
@@ -542,11 +542,11 @@
     }
 
     private static boolean isJDK9OrHigher() {
-        return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
+        return GraalServices.JAVA_SPECIFICATION_VERSION >= 9;
     }
 
     private static boolean isJDK10OrHigher() {
-        return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10;
+        return GraalServices.JAVA_SPECIFICATION_VERSION >= 10;
     }
 
     private static String getHostArchitectureName() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -105,7 +105,6 @@
     public void testVMCompilation3() throws IOException, InterruptedException {
         final int maxProblems = 4;
         Probe[] probes = {
-                        new Probe("To capture more information for diagnosing or reporting a compilation", maxProblems),
                         new Probe("Retrying compilation of", maxProblems) {
                             @Override
                             String test() {
@@ -131,6 +130,7 @@
         testHelper(Collections.emptyList(),
                         Arrays.asList(
                                         "-Dgraal.CompilationFailureAction=ExitVM",
+                                        "-Dgraal.TrufflePerformanceWarningsAreFatal=true",
                                         "-Dgraal.CrashAt=root test1"),
                         "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
     }
@@ -151,6 +151,22 @@
                         "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
     }
 
+    /**
+     * Tests that TrufflePerformanceWarningsAreFatal generates diagnostic output.
+     */
+    @Test
+    public void testTruffleCompilation3() throws IOException, InterruptedException {
+        Probe[] probes = {
+                        new Probe("Exiting VM due to TrufflePerformanceWarningsAreFatal=true", 1),
+        };
+        testHelper(Arrays.asList(probes),
+                        Arrays.asList(
+                                        "-Dgraal.CompilationFailureAction=Silent",
+                                        "-Dgraal.TrufflePerformanceWarningsAreFatal=true",
+                                        "-Dgraal.CrashAt=root test1:PermanentBailout"),
+                        "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
+    }
+
     private static final boolean VERBOSE = Boolean.getBoolean(CompilationWrapperTest.class.getSimpleName() + ".verbose");
 
     private static void testHelper(List<Probe> initialProbes, List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException {
@@ -225,7 +241,7 @@
                     Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
                 }
                 if (cfg == 0) {
-                    Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
+                    Assert.fail(String.format("Expected at least one .cfg file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
                 }
             } finally {
                 zip.delete();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries;
 import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes;
 import static org.graalvm.compiler.hotspot.test.CompileTheWorld.Options.DESCRIPTORS;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import java.io.Closeable;
 import java.io.File;
@@ -66,10 +66,12 @@
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.bytecode.Bytecodes;
 import org.graalvm.compiler.core.CompilerThreadFactory;
@@ -86,7 +88,7 @@
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.options.OptionsParser;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
@@ -107,8 +109,8 @@
 
     /**
      * Magic token to denote that JDK classes are to be compiled. If
-     * {@link JDK9Method#Java8OrEarlier}, then the classes in {@code rt.jar} are compiled. Otherwise
-     * the classes in the Java runtime image are compiled.
+     * {@link GraalServices#Java8OrEarlier}, then the classes in {@code rt.jar} are compiled.
+     * Otherwise the classes in the Java runtime image are compiled.
      */
     public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path";
 
@@ -379,6 +381,11 @@
             return new URLClassLoader(new URL[]{url});
         }
 
+        /**
+         * @see "https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Multi-release"
+         */
+        static Pattern MultiReleaseJarVersionedClassRE = Pattern.compile("META-INF/versions/[1-9][0-9]*/(.+)");
+
         @Override
         public List<String> getClassNames() throws IOException {
             Enumeration<JarEntry> e = jarFile.entries();
@@ -389,6 +396,17 @@
                     continue;
                 }
                 String className = je.getName().substring(0, je.getName().length() - ".class".length());
+                if (className.equals("module-info")) {
+                    continue;
+                }
+                if (className.startsWith("META-INF/versions/")) {
+                    Matcher m = MultiReleaseJarVersionedClassRE.matcher(className);
+                    if (m.matches()) {
+                        className = m.group(1);
+                    } else {
+                        continue;
+                    }
+                }
                 classNames.add(className.replace('/', '.'));
             }
             return classNames;
@@ -562,6 +580,10 @@
                         continue;
                     }
 
+                    if (!isClassIncluded(className)) {
+                        continue;
+                    }
+
                     try {
                         // Load and initialize class
                         Class<?> javaClass = Class.forName(className, true, loader);
@@ -581,14 +603,6 @@
                             continue;
                         }
 
-                        /*
-                         * Only check filters after class loading and resolution to mitigate impact
-                         * on reproducibility.
-                         */
-                        if (!isClassIncluded(className)) {
-                            continue;
-                        }
-
                         // Are we compiling this class?
                         MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
                         if (classFileCounter >= startAt) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,6 @@
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.MonitorInfo;
-import java.lang.management.RuntimeMXBean;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
 import java.util.Collection;
@@ -32,7 +31,7 @@
 import java.util.HashSet;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.debug.DebugContext;
@@ -41,6 +40,7 @@
 import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.BeforeClass;
@@ -58,11 +58,6 @@
 
     @BeforeClass
     public static void checkVMArguments() {
-        try {
-            Class.forName("java.lang.management.ManagementFactory");
-        } catch (ClassNotFoundException ex) {
-            Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
-        }
         /*
          * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from
          * working as every method is compiled at level3 (followed by level4 on the second
@@ -71,8 +66,8 @@
          * installed nmethod at a given BCI.
          *
          */
-        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
-        List<String> arguments = runtimeMxBean.getInputArguments();
+        List<String> arguments = GraalServices.getInputArguments();
+        Assume.assumeTrue("cannot check for monitors without", arguments != null);
         for (String arg : arguments) {
             Assume.assumeFalse(arg.equals(COMPILE_ONLY_FLAG));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,6 +26,9 @@
 import org.junit.Assert;
 import org.junit.Test;
 
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 /**
  * Test on-stack-replacement with Graal. The test manually triggers a Graal OSR-compilation which is
  * later invoked when hitting the backedge counter overflow.
@@ -99,4 +102,57 @@
         return ret;
     }
 
+    @Test
+    public void testOSR04() {
+        testFunnyOSR("testDoWhile", GraalOSRTest::testDoWhile);
+    }
+
+    @Test
+    public void testOSR05() {
+        testFunnyOSR("testDoWhileLocked", GraalOSRTest::testDoWhileLocked);
+    }
+
+    /**
+     * Because of a bug in C1 profile collection HotSpot can sometimes request an OSR compilation
+     * for a backedge which isn't ever taken. This test synthetically creates that situation.
+     */
+    private void testFunnyOSR(String name, Runnable warmup) {
+        ResolvedJavaMethod method = getResolvedJavaMethod(name);
+        int iterations = 0;
+        while (true) {
+            ProfilingInfo profilingInfo = method.getProfilingInfo();
+            if (profilingInfo.isMature()) {
+                break;
+            }
+
+            warmup.run();
+            if (iterations++ % 1000 == 0) {
+                System.err.print('.');
+            }
+            if (iterations > 200000) {
+                throw new AssertionError("no profile");
+            }
+        }
+        compileOSR(getInitialOptions(), method);
+        Result result = executeExpected(method, null);
+        checkResult(result);
+    }
+
+    private static boolean repeatLoop;
+
+    public static ReturnValue testDoWhile() {
+        do {
+            sideEffect++;
+        } while (repeatLoop);
+        return ReturnValue.SUCCESS;
+    }
+
+    public static synchronized ReturnValue testDoWhileLocked() {
+        // synchronized (GraalOSRTest.class) {
+        do {
+            sideEffect++;
+        } while (repeatLoop);
+        // }
+        return ReturnValue.SUCCESS;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,6 +29,8 @@
 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
 import org.graalvm.compiler.bytecode.BytecodeStream;
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
+import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
+import org.graalvm.compiler.core.GraalCompilerOptions;
 import org.graalvm.compiler.core.target.Backend;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
@@ -95,18 +97,18 @@
      * Returns the target BCI of the first bytecode backedge. This is where HotSpot triggers
      * on-stack-replacement in case the backedge counter overflows.
      */
-    private static int getBackedgeBCI(DebugContext debug, ResolvedJavaMethod method) {
+    static int getBackedgeBCI(DebugContext debug, ResolvedJavaMethod method) {
         Bytecode code = new ResolvedJavaMethodBytecode(method);
         BytecodeStream stream = new BytecodeStream(code.getCode());
         OptionValues options = debug.getOptions();
         BciBlockMapping bciBlockMapping = BciBlockMapping.create(stream, code, options, debug);
 
         for (BciBlock block : bciBlockMapping.getBlocks()) {
-            if (block.startBci != -1) {
-                int bci = block.startBci;
+            if (block.getStartBci() != -1) {
+                int bci = block.getEndBci();
                 for (BciBlock succ : block.getSuccessors()) {
-                    if (succ.startBci != -1) {
-                        int succBci = succ.startBci;
+                    if (succ.getStartBci() != -1) {
+                        int succBci = succ.getStartBci();
                         if (succBci < bci) {
                             // back edge
                             return succBci;
@@ -120,16 +122,22 @@
         return -1;
     }
 
-    private static void checkResult(Result result) {
+    protected static void checkResult(Result result) {
         Assert.assertNull("Unexpected exception", result.exception);
         Assert.assertNotNull(result.returnValue);
         Assert.assertTrue(result.returnValue instanceof ReturnValue);
         Assert.assertEquals(ReturnValue.SUCCESS, result.returnValue);
     }
 
-    private void compileOSR(OptionValues options, ResolvedJavaMethod method) {
+    protected void compileOSR(OptionValues options, ResolvedJavaMethod method) {
+        OptionValues goptions = options;
+        // Silence diagnostics for permanent bailout errors as they
+        // are expected for some OSR tests.
+        if (!GraalCompilerOptions.CompilationBailoutAction.hasBeenSet(options)) {
+            goptions = new OptionValues(options, GraalCompilerOptions.CompilationBailoutAction, ExceptionAction.Silent);
+        }
         // ensure eager resolving
-        StructuredGraph graph = parseEager(method, AllowAssumptions.YES, options);
+        StructuredGraph graph = parseEager(method, AllowAssumptions.YES, goptions);
         DebugContext debug = graph.getDebug();
         int bci = getBackedgeBCI(debug, method);
         assert bci != -1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Field;
-import java.util.Arrays;
-
-import javax.management.Attribute;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.test.GraalTest;
-import org.junit.Assume;
-import org.junit.Test;
-
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-public class HotSpotGraalMBeanTest {
-
-    public HotSpotGraalMBeanTest() {
-        // No support for registering Graal MBean yet on JDK9 (GR-4025). We cannot
-        // rely on an exception being thrown when accessing ManagementFactory.platformMBeanServer
-        // via reflection as recent JDK9 changes now allow this and issue a warning instead.
-        Assume.assumeTrue(GraalTest.Java8OrEarlier);
-    }
-
-    @Test
-    public void registration() throws Exception {
-        ObjectName name;
-
-        Field field = null;
-        try {
-            field = stopMBeanServer();
-        } catch (Exception ex) {
-            if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) {
-                // skip on JDK9
-                return;
-            }
-        }
-        assertNull("The platformMBeanServer isn't initialized now", field.get(null));
-
-        HotSpotGraalMBean bean = HotSpotGraalMBean.create(null);
-        assertNotNull("Bean created", bean);
-
-        assertNull("It is not registered yet", bean.ensureRegistered(true));
-
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-
-        assertNotNull("Now the bean thinks it is registered", name = bean.ensureRegistered(true));
-
-        assertNotNull("And the bean is found", server.getObjectInstance(name));
-    }
-
-    private static Field stopMBeanServer() throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException {
-        final Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer");
-        field.setAccessible(true);
-        field.set(null, null);
-        return field;
-    }
-
-    @Test
-    public void readBeanInfo() throws Exception {
-        ObjectName name;
-
-        assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
-
-        HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
-        assertNotNull("Bean is registered", name = realBean.ensureRegistered(false));
-        final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-
-        ObjectInstance bean = server.getObjectInstance(name);
-        assertNotNull("Bean is registered", bean);
-        MBeanInfo info = server.getMBeanInfo(name);
-        assertNotNull("Info is found", info);
-
-        MBeanAttributeInfo printCompilation = (MBeanAttributeInfo) findAttributeInfo("PrintCompilation", info);
-        assertNotNull("PrintCompilation found", printCompilation);
-        assertEquals("true/false", Boolean.class.getName(), printCompilation.getType());
-
-        Attribute printOn = new Attribute(printCompilation.getName(), Boolean.TRUE);
-
-        Object before = server.getAttribute(name, printCompilation.getName());
-        server.setAttribute(name, printOn);
-        Object after = server.getAttribute(name, printCompilation.getName());
-
-        assertNull("Default value was not set", before);
-        assertEquals("Changed to on", Boolean.TRUE, after);
-    }
-
-    private static Object findAttributeInfo(String attrName, Object info) {
-        MBeanAttributeInfo printCompilation = null;
-        for (MBeanAttributeInfo attr : ((MBeanInfo) info).getAttributes()) {
-            if (attr.getName().equals(attrName)) {
-                assertTrue("Readable", attr.isReadable());
-                assertTrue("Writable", attr.isWritable());
-                printCompilation = attr;
-                break;
-            }
-        }
-        return printCompilation;
-    }
-
-    @Test
-    public void optionsAreCached() throws Exception {
-        ObjectName name;
-
-        assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
-
-        HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
-
-        OptionValues original = new OptionValues(EconomicMap.create());
-
-        assertSame(original, realBean.optionsFor(original, null));
-
-        assertNotNull("Bean is registered", name = realBean.ensureRegistered(false));
-        final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-
-        ObjectInstance bean = server.getObjectInstance(name);
-        assertNotNull("Bean is registered", bean);
-        MBeanInfo info = server.getMBeanInfo(name);
-        assertNotNull("Info is found", info);
-
-        MBeanAttributeInfo dump = (MBeanAttributeInfo) findAttributeInfo("Dump", info);
-
-        Attribute dumpTo1 = new Attribute(dump.getName(), 1);
-
-        server.setAttribute(name, dumpTo1);
-        Object after = server.getAttribute(name, dump.getName());
-        assertEquals(1, after);
-
-        final OptionValues modified1 = realBean.optionsFor(original, null);
-        assertNotSame(original, modified1);
-        final OptionValues modified2 = realBean.optionsFor(original, null);
-        assertSame("Options are cached", modified1, modified2);
-
-    }
-
-    @Test
-    public void dumpOperation() throws Exception {
-        Field field = null;
-        try {
-            field = stopMBeanServer();
-        } catch (Exception ex) {
-            if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) {
-                // skip on JDK9
-                return;
-            }
-        }
-        assertNull("The platformMBeanServer isn't initialized now", field.get(null));
-
-        ObjectName name;
-
-        assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
-
-        HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
-
-        assertNotNull("Bean is registered", name = realBean.ensureRegistered(false));
-        final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-
-        ObjectInstance bean = server.getObjectInstance(name);
-        assertNotNull("Bean is registered", bean);
-
-        MBeanInfo info = server.getMBeanInfo(name);
-        assertNotNull("Info is found", info);
-
-        final MBeanOperationInfo[] arr = info.getOperations();
-        assertEquals("Currently three overloads", 3, arr.length);
-        MBeanOperationInfo dumpOp = null;
-        for (int i = 0; i < arr.length; i++) {
-            assertEquals("dumpMethod", arr[i].getName());
-            if (arr[i].getSignature().length == 3) {
-                dumpOp = arr[i];
-            }
-        }
-        assertNotNull("three args variant found", dumpOp);
-
-        server.invoke(name, "dumpMethod", new Object[]{
-                        "java.util.Arrays", "asList", ":3"
-        }, null);
-
-        MBeanAttributeInfo dump = (MBeanAttributeInfo) findAttributeInfo("Dump", info);
-        Attribute dumpTo1 = new Attribute(dump.getName(), "");
-        server.setAttribute(name, dumpTo1);
-        Object after = server.getAttribute(name, dump.getName());
-        assertEquals("", after);
-
-        OptionValues empty = new OptionValues(EconomicMap.create());
-        OptionValues unsetDump = realBean.optionsFor(empty, null);
-        final MetaAccessProvider metaAccess = jdk.vm.ci.runtime.JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
-        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Arrays.class.getMethod("asList", Object[].class));
-        final OptionValues forMethod = realBean.optionsFor(unsetDump, method);
-        assertNotSame(unsetDump, forMethod);
-        Object nothing = unsetDump.getMap().get(DebugOptions.Dump);
-        assertEquals("Empty string", "", nothing);
-
-        Object specialValue = forMethod.getMap().get(DebugOptions.Dump);
-        assertEquals(":3", specialValue);
-
-        OptionValues normalMethod = realBean.optionsFor(unsetDump, null);
-        Object noSpecialValue = normalMethod.getMap().get(DebugOptions.Dump);
-        assertEquals("Empty string", "", noSpecialValue);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.test;
+
+import static org.graalvm.compiler.hotspot.test.HotSpotGraalManagementTest.JunitShield.findAttributeInfo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+import org.graalvm.compiler.api.test.Graal;
+import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
+import org.graalvm.compiler.options.EnumOptionKey;
+import org.graalvm.compiler.options.NestedBooleanOptionKey;
+import org.graalvm.compiler.options.OptionDescriptor;
+import org.graalvm.compiler.options.OptionDescriptors;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionsParser;
+import org.junit.Assert;
+import org.junit.AssumptionViolatedException;
+import org.junit.Test;
+
+public class HotSpotGraalManagementTest {
+
+    private static final boolean DEBUG = Boolean.getBoolean(HotSpotGraalManagementTest.class.getSimpleName() + ".debug");
+
+    public HotSpotGraalManagementTest() {
+        try {
+            MBeanServerFactory.findMBeanServer(null);
+        } catch (NoClassDefFoundError e) {
+            throw new AssumptionViolatedException("Management classes/module(s) not available: " + e);
+        }
+    }
+
+    @Test
+    public void registration() throws Exception {
+        HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime();
+        HotSpotGraalManagementRegistration management = runtime.getManagement();
+        if (management == null) {
+            return;
+        }
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectName name;
+        assertNotNull("Now the bean thinks it is registered", name = (ObjectName) management.poll(true));
+
+        assertNotNull("And the bean is found", server.getObjectInstance(name));
+    }
+
+    @Test
+    public void readBeanInfo() throws Exception {
+
+        assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
+
+        HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime();
+        HotSpotGraalManagementRegistration management = runtime.getManagement();
+        if (management == null) {
+            return;
+        }
+
+        ObjectName mbeanName;
+        assertNotNull("Bean is registered", mbeanName = (ObjectName) management.poll(true));
+        final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectInstance bean = server.getObjectInstance(mbeanName);
+        assertNotNull("Bean is registered", bean);
+        MBeanInfo info = server.getMBeanInfo(mbeanName);
+        assertNotNull("Info is found", info);
+
+        AttributeList originalValues = new AttributeList();
+        AttributeList newValues = new AttributeList();
+        for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
+            for (OptionDescriptor option : set) {
+                JunitShield.testOption(info, mbeanName, server, runtime, option, newValues, originalValues);
+            }
+        }
+
+        String[] attributeNames = new String[originalValues.size()];
+        for (int i = 0; i < attributeNames.length; i++) {
+            attributeNames[i] = ((Attribute) originalValues.get(i)).getName();
+        }
+        AttributeList actualValues = server.getAttributes(mbeanName, attributeNames);
+        assertEquals(originalValues.size(), actualValues.size());
+        for (int i = 0; i < attributeNames.length; i++) {
+            Object expect = String.valueOf(((Attribute) originalValues.get(i)).getValue());
+            Object actual = String.valueOf(((Attribute) actualValues.get(i)).getValue());
+            assertEquals(attributeNames[i], expect, actual);
+        }
+
+        try {
+            server.setAttributes(mbeanName, newValues);
+        } finally {
+            server.setAttributes(mbeanName, originalValues);
+        }
+    }
+
+    /**
+     * Junit scans all methods of a test class and tries to resolve all method parameter and return
+     * types. We hide such methods in an inner class to prevent errors such as:
+     *
+     * <pre>
+     * java.lang.NoClassDefFoundError: javax/management/MBeanInfo
+     *     at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
+     *     at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3119)
+     *     at java.base/java.lang.Class.getDeclaredMethods(Class.java:2268)
+     *     at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:54)
+     *     at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:65)
+     *     at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
+     *
+     * </pre>
+     */
+    static class JunitShield {
+
+        /**
+         * Tests changing the value of {@code option} via the management interface to a) a new legal
+         * value and b) an illegal value.
+         */
+        static void testOption(MBeanInfo mbeanInfo,
+                        ObjectName mbeanName,
+                        MBeanServer server,
+                        HotSpotGraalRuntime runtime,
+                        OptionDescriptor option,
+                        AttributeList newValues,
+                        AttributeList originalValues) throws Exception {
+            OptionKey<?> optionKey = option.getOptionKey();
+            Object currentValue = optionKey.getValue(runtime.getOptions());
+            Class<?> optionType = option.getOptionValueType();
+            String name = option.getName();
+            if (DEBUG) {
+                System.out.println("Testing option " + name);
+            }
+            MBeanAttributeInfo attrInfo = findAttributeInfo(name, mbeanInfo);
+            assertNotNull("Attribute not found for option " + name, attrInfo);
+
+            String expectAttributeValue = stringValue(currentValue, option.getOptionValueType() == String.class);
+            Object actualAttributeValue = server.getAttribute(mbeanName, name);
+            assertEquals(expectAttributeValue, actualAttributeValue);
+
+            Map<String, String> legalValues = new HashMap<>();
+            List<String> illegalValues = new ArrayList<>();
+            if (optionKey instanceof EnumOptionKey) {
+                EnumOptionKey<?> enumOptionKey = (EnumOptionKey<?>) optionKey;
+                for (Object obj : enumOptionKey.getAllValues()) {
+                    if (obj != currentValue) {
+                        legalValues.put(obj.toString(), obj.toString());
+                    }
+                }
+                illegalValues.add(String.valueOf(42));
+            } else if (optionType == Boolean.class) {
+                Object defaultValue;
+                if (optionKey instanceof NestedBooleanOptionKey) {
+                    NestedBooleanOptionKey nbok = (NestedBooleanOptionKey) optionKey;
+                    defaultValue = nbok.getMasterOption().getValue(runtime.getOptions());
+                } else {
+                    defaultValue = optionKey.getDefaultValue();
+                }
+                legalValues.put("", unquotedStringValue(defaultValue));
+                illegalValues.add(String.valueOf(42));
+                illegalValues.add("true");
+                illegalValues.add("false");
+            } else if (optionType == String.class) {
+                legalValues.put("", quotedStringValue(optionKey.getDefaultValue()));
+                legalValues.put("\"" + currentValue + "Prime\"", "\"" + currentValue + "Prime\"");
+                legalValues.put("\"quoted string\"", "\"quoted string\"");
+                illegalValues.add("\"unbalanced quotes");
+                illegalValues.add("\"");
+                illegalValues.add("non quoted string");
+            } else if (optionType == Float.class) {
+                legalValues.put("", unquotedStringValue(optionKey.getDefaultValue()));
+                String value = unquotedStringValue(currentValue == null ? 33F : ((float) currentValue) + 11F);
+                legalValues.put(value, value);
+                illegalValues.add("string");
+            } else if (optionType == Double.class) {
+                legalValues.put("", unquotedStringValue(optionKey.getDefaultValue()));
+                String value = unquotedStringValue(currentValue == null ? 33D : ((double) currentValue) + 11D);
+                legalValues.put(value, value);
+                illegalValues.add("string");
+            } else if (optionType == Integer.class) {
+                legalValues.put("", unquotedStringValue(optionKey.getDefaultValue()));
+                String value = unquotedStringValue(currentValue == null ? 33 : ((int) currentValue) + 11);
+                legalValues.put(value, value);
+                illegalValues.add("42.42");
+                illegalValues.add("string");
+            } else if (optionType == Long.class) {
+                legalValues.put("", unquotedStringValue(optionKey.getDefaultValue()));
+                String value = unquotedStringValue(currentValue == null ? 33L : ((long) currentValue) + 11L);
+                legalValues.put(value, value);
+                illegalValues.add("42.42");
+                illegalValues.add("string");
+            }
+
+            Attribute originalAttributeValue = new Attribute(name, expectAttributeValue);
+            try {
+                for (Map.Entry<String, String> e : legalValues.entrySet()) {
+                    String legalValue = e.getKey();
+                    if (DEBUG) {
+                        System.out.printf("Changing %s from %s to %s%n", name, currentValue, legalValue);
+                    }
+                    Attribute newAttributeValue = new Attribute(name, legalValue);
+                    newValues.add(newAttributeValue);
+                    server.setAttribute(mbeanName, newAttributeValue);
+                    Object actual = optionKey.getValue(runtime.getOptions());
+                    actual = server.getAttribute(mbeanName, name);
+                    String expectValue = e.getValue();
+                    if (option.getOptionValueType() == String.class && expectValue == null) {
+                        expectValue = "";
+                    } else if (option.getOptionKey() instanceof NestedBooleanOptionKey && null == expectValue) {
+                        NestedBooleanOptionKey nbok = (NestedBooleanOptionKey) option.getOptionKey();
+                        expectValue = String.valueOf(nbok.getValue(runtime.getOptions()));
+                        actual = server.getAttribute(mbeanName, name);
+                    }
+                    assertEquals(expectValue, actual);
+                }
+            } finally {
+                if (DEBUG) {
+                    System.out.printf("Resetting %s to %s%n", name, currentValue);
+                }
+                originalValues.add(originalAttributeValue);
+                server.setAttribute(mbeanName, originalAttributeValue);
+            }
+
+            try {
+                for (Object illegalValue : illegalValues) {
+                    if (DEBUG) {
+                        System.out.printf("Changing %s from %s to illegal value %s%n", name, currentValue, illegalValue);
+                    }
+                    server.setAttribute(mbeanName, new Attribute(name, illegalValue));
+                    Assert.fail("Expected setting " + name + " to " + illegalValue + " to fail");
+                }
+            } catch (InvalidAttributeValueException e) {
+                // Expected
+            } finally {
+                if (DEBUG) {
+                    System.out.printf("Resetting %s to %s%n", name, currentValue);
+                }
+                server.setAttribute(mbeanName, originalAttributeValue);
+            }
+
+            try {
+
+                String unknownOptionName = "definitely not an option name";
+                server.setAttribute(mbeanName, new Attribute(unknownOptionName, ""));
+                Assert.fail("Expected setting option with name \"" + unknownOptionName + "\" to fail");
+            } catch (AttributeNotFoundException e) {
+                // Expected
+            }
+        }
+
+        static MBeanAttributeInfo findAttributeInfo(String attrName, MBeanInfo info) {
+            for (MBeanAttributeInfo attr : info.getAttributes()) {
+                if (attr.getName().equals(attrName)) {
+                    assertTrue("Readable", attr.isReadable());
+                    assertTrue("Writable", attr.isWritable());
+                    return attr;
+                }
+            }
+            return null;
+        }
+    }
+
+    private static String quotedStringValue(Object optionValue) {
+        return stringValue(optionValue, true);
+    }
+
+    private static String unquotedStringValue(Object optionValue) {
+        return stringValue(optionValue, false);
+    }
+
+    private static String stringValue(Object optionValue, boolean withQuoting) {
+        if (optionValue == null) {
+            return "";
+        }
+        if (withQuoting) {
+            return "\"" + optionValue + "\"";
+        }
+        return String.valueOf(optionValue);
+    }
+
+    private static String quoted(Object s) {
+        return "\"" + s + "\"";
+    }
+
+    /**
+     * Tests publicaly visible names and identifiers used by tools developed and distributed on an
+     * independent schedule (like VisualVM). Consider keeping the test passing without any semantic
+     * modifications. The cost of changes is higher than you estimate. Include all available
+     * stakeholders as reviewers to give them a chance to stop you before causing too much damage.
+     */
+    @Test
+    public void publicJmxApiOfGraalDumpOperation() throws Exception {
+        assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
+
+        HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime();
+        HotSpotGraalManagementRegistration management = runtime.getManagement();
+        if (management == null) {
+            return;
+        }
+
+        ObjectName mbeanName;
+        assertNotNull("Bean is registered", mbeanName = (ObjectName) management.poll(true));
+        final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        assertEquals("Domain name is used to lookup the beans by VisualVM", "org.graalvm.compiler.hotspot", mbeanName.getDomain());
+        assertEquals("type can be used to identify the Graal bean", "HotSpotGraalRuntime_VM", mbeanName.getKeyProperty("type"));
+
+        ObjectInstance bean = server.getObjectInstance(mbeanName);
+        assertNotNull("Bean is registered", bean);
+
+        MBeanInfo info = server.getMBeanInfo(mbeanName);
+        assertNotNull("Info is found", info);
+
+        final MBeanOperationInfo[] arr = info.getOperations();
+        assertEquals("Currently three overloads", 3, arr.length);
+        MBeanOperationInfo dumpOp = null;
+        for (int i = 0; i < arr.length; i++) {
+            assertEquals("dumpMethod", arr[i].getName());
+            if (arr[i].getSignature().length == 3) {
+                dumpOp = arr[i];
+            }
+        }
+        assertNotNull("three args variant (as used by VisualVM) found", dumpOp);
+
+        MBeanAttributeInfo dumpPath = findAttributeInfo("DumpPath", info);
+        MBeanAttributeInfo printGraphFile = findAttributeInfo("PrintGraphFile", info);
+        MBeanAttributeInfo showDumpFiles = findAttributeInfo("ShowDumpFiles", info);
+        Object originalDumpPath = server.getAttribute(mbeanName, dumpPath.getName());
+        Object originalPrintGraphFile = server.getAttribute(mbeanName, printGraphFile.getName());
+        Object originalShowDumpFiles = server.getAttribute(mbeanName, showDumpFiles.getName());
+        final File tmpDir = new File(HotSpotGraalManagementTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile();
+
+        server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), quoted(tmpDir)));
+        // Force output to a file even if there's a running IGV instance available.
+        server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), true));
+        server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), false));
+        Object[] params = {"java.util.Arrays", "asList", ":3"};
+        try {
+            server.invoke(mbeanName, "dumpMethod", params, null);
+            boolean found = false;
+            String expectedIgvDumpSuffix = "[Arrays.asList(Object[])List].bgv";
+            List<String> dumpPathEntries = Arrays.asList(tmpDir.list());
+            for (String entry : dumpPathEntries) {
+                if (entry.endsWith(expectedIgvDumpSuffix)) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                Assert.fail(String.format("Expected file ending with \"%s\" in %s but only found:%n%s", expectedIgvDumpSuffix, tmpDir,
+                                dumpPathEntries.stream().collect(Collectors.joining(System.lineSeparator()))));
+            }
+        } finally {
+            deleteDirectory(tmpDir.toPath());
+            server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), originalDumpPath));
+            server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), originalPrintGraphFile));
+            server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), originalShowDumpFiles));
+        }
+    }
+
+    static void deleteDirectory(Path toDelete) throws IOException {
+        Files.walk(toDelete).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -46,6 +46,17 @@
 
         test("getClass0", "a string");
         test("objectHashCode", obj);
+
+        testGraph("objectNotify", "Object.notify");
+        testGraph("objectNotifyAll", "Object.notifyAll");
+
+        synchronized (obj) {
+            test("objectNotify", obj);
+            test("objectNotifyAll", obj);
+        }
+        // Test with IllegalMonitorStateException (no synchronized block)
+        test("objectNotify", obj);
+        test("objectNotifyAll", obj);
     }
 
     @SuppressWarnings("all")
@@ -58,6 +69,16 @@
         return obj.hashCode();
     }
 
+    @SuppressWarnings("all")
+    public static void objectNotify(Object obj) {
+        obj.notify();
+    }
+
+    @SuppressWarnings("all")
+    public static void objectNotifyAll(Object obj) {
+        obj.notifyAll();
+    }
+
     @Test
     public void testClassSubstitutions() {
         testGraph("getModifiers");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStampMemoryAccessTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStampMemoryAccessTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,6 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp;
 import org.junit.Assume;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.JavaConstant;
@@ -37,7 +36,6 @@
 
 public class HotSpotStampMemoryAccessTest extends HotSpotGraalCompilerTest {
 
-    @Ignore("not all versions are safe yet")
     @Test
     public void testReadNarrowObject() {
         CompressEncoding oopEncoding = runtime().getVMConfig().getOopEncoding();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Scope;
@@ -59,7 +59,7 @@
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.Test;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/aaa	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.test;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.hotspot.meta.HotSpotClassInitializationPlugin;
+import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
+import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class HotSpotLazyInitializationTest extends GraalCompilerTest {
+
+    HotSpotClassInitializationPlugin classInitPlugin = new HotSpotClassInitializationPlugin();
+
+    @Override
+    protected Plugins getDefaultGraphBuilderPlugins() {
+        Plugins plugins = super.getDefaultGraphBuilderPlugins();
+        plugins.setClassInitializationPlugin(classInitPlugin);
+        return plugins;
+    }
+
+    static boolean X_initialized = false;
+
+    static class X {
+        static {
+            X_initialized = true;
+        }
+        static void foo() {}
+    }
+
+    public static void invokeStatic() {
+        X.foo();
+    }
+
+    private void test(String name) {
+        ResolvedJavaMethod method = getResolvedJavaMethod(name);
+        Assume.assumeTrue("skipping for old JVMCI", classInitPlugin.supportsLazyInitialization(method.getConstantPool()));
+        StructuredGraph graph = parseEager(method, AllowAssumptions.NO);
+        Assert.assertFalse(X_initialized);
+    }
+
+    @Test
+    public void test1() {
+        test("invokeStatic");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CommunityCompilerConfigurationFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import org.graalvm.compiler.core.phases.CommunityCompilerConfiguration;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+
+/**
+ * Factory for creating the default configuration for the community edition of Graal.
+ */
+@ServiceProvider(CompilerConfigurationFactory.class)
+public class CommunityCompilerConfigurationFactory extends CompilerConfigurationFactory {
+
+    public static final String NAME = "community";
+
+    /**
+     * Must be greater than {@link EconomyCompilerConfigurationFactory#AUTO_SELECTION_PRIORITY}.
+     */
+    public static final int AUTO_SELECTION_PRIORITY = 2;
+
+    public CommunityCompilerConfigurationFactory() {
+        super(NAME, AUTO_SELECTION_PRIORITY);
+        assert AUTO_SELECTION_PRIORITY > EconomyCompilerConfigurationFactory.AUTO_SELECTION_PRIORITY;
+    }
+
+    @Override
+    public CompilerConfiguration createCompilerConfiguration() {
+        return new CommunityCompilerConfiguration();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,10 +42,10 @@
 import java.util.concurrent.ConcurrentLinkedDeque;
 
 import org.graalvm.compiler.debug.CSVUtil;
-import org.graalvm.compiler.debug.Management;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
@@ -87,8 +87,7 @@
     private static long zeroTime = System.nanoTime();
 
     private static long getThreadAllocatedBytes() {
-        com.sun.management.ThreadMXBean thread = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
-        return thread.getThreadAllocatedBytes(currentThread().getId());
+        return GraalServices.getCurrentThreadAllocatedBytes();
     }
 
     @NotReported private final long startTime;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,14 +22,16 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Diagnose;
 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
+import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
 import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.CompilationPrinter;
@@ -140,17 +142,25 @@
         }
 
         @Override
-        protected ExceptionAction lookupAction(OptionValues values, EnumOptionKey<ExceptionAction> actionKey) {
-            /*
-             * Automatically exit VM on non-bailout during bootstrap or when asserts are enabled but
-             * respect CompilationFailureAction if it has been explicitly set.
-             */
-            if (actionKey == CompilationFailureAction && !actionKey.hasBeenSet(values)) {
-                if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
-                    return ExitVM;
+        protected ExceptionAction lookupAction(OptionValues values, EnumOptionKey<ExceptionAction> actionKey, Throwable cause) {
+            // Respect current action if it has been explicitly set.
+            if (!actionKey.hasBeenSet(values)) {
+                if (actionKey == CompilationFailureAction) {
+                    // Automatically exit on non-bailout during bootstrap
+                    // or when assertions are enabled.
+                    if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
+                        return ExitVM;
+                    }
+                } else if (actionKey == CompilationBailoutAction && ((BailoutException) cause).isPermanent()) {
+                    // Get more info for permanent bailouts during bootstrap
+                    // or when assertions are enabled.
+                    assert CompilationBailoutAction.getDefaultValue() == ExceptionAction.Silent;
+                    if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
+                        return Diagnose;
+                    }
                 }
             }
-            return super.lookupAction(values, actionKey);
+            return super.lookupAction(values, actionKey, cause);
         }
 
         @SuppressWarnings("try")
@@ -187,6 +197,7 @@
             }
             return null;
         }
+
     }
 
     public CompilationTask(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,7 +31,7 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.lir.phases.LIRPhase;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CoreCompilerConfigurationFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot;
-
-import org.graalvm.compiler.core.phases.CoreCompilerConfiguration;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-import org.graalvm.compiler.serviceprovider.ServiceProvider;
-
-@ServiceProvider(CompilerConfigurationFactory.class)
-public class CoreCompilerConfigurationFactory extends CompilerConfigurationFactory {
-
-    public static final String NAME = "core";
-
-    public static final int AUTO_SELECTION_PRIORITY = 2;
-
-    public CoreCompilerConfigurationFactory() {
-        super(NAME, AUTO_SELECTION_PRIORITY);
-    }
-
-    @Override
-    public CompilerConfiguration createCompilerConfiguration() {
-        return new CoreCompilerConfiguration();
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EconomyCompilerConfigurationFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EconomyCompilerConfigurationFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,6 +26,9 @@
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
 
+/**
+ * Factory that creates a {@link EconomyCompilerConfiguration}.
+ */
 @ServiceProvider(CompilerConfigurationFactory.class)
 public class EconomyCompilerConfigurationFactory extends CompilerConfigurationFactory {
 
@@ -44,7 +47,7 @@
 
     @Override
     public BackendMap createBackendMap() {
-        // the economy configuration only differs in the frontend, it reuses the "core" backend
-        return new DefaultBackendMap(CoreCompilerConfigurationFactory.NAME);
+        // the economy configuration only differs in the frontend, it reuses the "community" backend
+        return new DefaultBackendMap(CommunityCompilerConfigurationFactory.NAME);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,33 +25,16 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
-import org.graalvm.compiler.api.replacements.Fold;
-import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
 
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
 
 /**
  * Used to access native configuration details.
  */
-public class GraalHotSpotVMConfig extends HotSpotVMConfigAccess {
-
-    /**
-     * Sentinel value to use for an {@linkplain InjectedParameter injected}
-     * {@link GraalHotSpotVMConfig} parameter to a {@linkplain Fold foldable} method.
-     */
-    public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null;
-
-    // this uses `1.9` which will give the correct result with `1.9`, `9`, `10` etc.
-    private final boolean isJDK8 = System.getProperty("java.specification.version").compareTo("1.9") < 0;
-    private final int jdkVersion = isJDK8 ? 8 : Integer.parseInt(System.getProperty("java.specification.version"));
-    public final String osName = getHostOSName();
-    public final String osArch = getHostArchitectureName();
-    public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
-    public final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
+public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
 
     GraalHotSpotVMConfig(HotSpotVMConfigStore store) {
         super(store);
@@ -64,29 +47,6 @@
         assert check();
     }
 
-    /**
-     * Gets the value of a static C++ field under two possible names. {@code name} is the preferred
-     * name and will be checked first.
-     *
-     * @param name fully qualified name of the field
-     * @param alternateName fully qualified alternate name of the field
-     * @param type the boxed type to which the constant value will be converted
-     * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"})
-     * @return the value of the requested field
-     * @throws JVMCIError if the field is not static or not present
-     */
-    public <T> T getFieldValueWithAlternate(String name, String alternateName, Class<T> type, String cppType) {
-        try {
-            return getFieldValue(name, type, cppType);
-        } catch (JVMCIError e) {
-            try {
-                return getFieldValue(alternateName, type, cppType);
-            } catch (JVMCIError e2) {
-                throw new JVMCIError("expected VM field not found: " + name + " or " + alternateName);
-            }
-        }
-    }
-
     private final CompressEncoding oopEncoding;
     private final CompressEncoding klassEncoding;
 
@@ -98,50 +58,6 @@
         return klassEncoding;
     }
 
-    /**
-     * Gets the host operating system name.
-     */
-    private static String getHostOSName() {
-        String osName = System.getProperty("os.name");
-        switch (osName) {
-            case "Linux":
-                osName = "linux";
-                break;
-            case "SunOS":
-                osName = "solaris";
-                break;
-            case "Mac OS X":
-                osName = "bsd";
-                break;
-            default:
-                // Of course Windows is different...
-                if (osName.startsWith("Windows")) {
-                    osName = "windows";
-                } else {
-                    throw new JVMCIError("Unexpected OS name: " + osName);
-                }
-        }
-        return osName;
-    }
-
-    private static String getHostArchitectureName() {
-        String arch = System.getProperty("os.arch");
-        switch (arch) {
-            case "x86_64":
-                arch = "amd64";
-                break;
-            case "sparcv9":
-                arch = "sparc";
-                break;
-        }
-        return arch;
-    }
-
-    private final Integer intRequiredOnAMD64 = osArch.equals("amd64") ? null : 0;
-    private final Long longRequiredOnAMD64 = osArch.equals("amd64") ? null : 0L;
-    private final Integer intNotPresentInJDK8 = isJDK8 ? 0 : null;
-    private final Long longNotPresentInJDK8 = isJDK8 ? 0L : null;
-
     public final boolean cAssertions = getConstant("ASSERT", Boolean.class);
 
     public final int codeEntryAlignment = getFlag("CodeEntryAlignment", Integer.class);
@@ -157,6 +73,7 @@
     public final int hugeMethodLimit = getFlag("HugeMethodLimit", Integer.class);
     public final boolean printInlining = getFlag("PrintInlining", Boolean.class);
     public final boolean inline = getFlag("Inline", Boolean.class);
+    public final boolean inlineNotify = versioned.inlineNotify;
     public final boolean useFastLocking = getFlag("JVMCIUseFastLocking", Boolean.class);
     public final boolean forceUnreachable = getFlag("ForceUnreachable", Boolean.class);
     public final int codeSegmentSize = getFlag("CodeCacheSegmentSize", Integer.class);
@@ -168,7 +85,7 @@
     public final boolean usePopCountInstruction = getFlag("UsePopCountInstruction", Boolean.class);
     public final boolean useAESIntrinsics = getFlag("UseAESIntrinsics", Boolean.class);
     public final boolean useCRC32Intrinsics = getFlag("UseCRC32Intrinsics", Boolean.class);
-    public final boolean useCRC32CIntrinsics = isJDK8 ? false : getFlag("UseCRC32CIntrinsics", Boolean.class);
+    public final boolean useCRC32CIntrinsics = versioned.useCRC32CIntrinsics;
     public final boolean threadLocalHandshakes = getFlag("ThreadLocalHandshakes", Boolean.class, false);
 
     private final boolean useMultiplyToLenIntrinsic = getFlag("UseMultiplyToLenIntrinsic", Boolean.class);
@@ -216,6 +133,14 @@
         return useSquareToLenIntrinsic && squareToLen != 0;
     }
 
+    public boolean inlineNotify() {
+        return inlineNotify && notifyAddress != 0;
+    }
+
+    public boolean inlineNotifyAll() {
+        return inlineNotify && notifyAllAddress != 0;
+    }
+
     public final boolean useG1GC = getFlag("UseG1GC", Boolean.class);
     public final boolean useCMSGC = getFlag("UseConcMarkSweepGC", Boolean.class);
 
@@ -383,7 +308,7 @@
     public final int threadIsMethodHandleReturnOffset = getFieldOffset("JavaThread::_is_method_handle_return", Integer.class, "int");
     public final int threadObjectResultOffset = getFieldOffset("JavaThread::_vm_result", Integer.class, "oop");
     public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
-    public final int javaThreadReservedStackActivationOffset = getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address", intNotPresentInJDK8);
+    public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
 
     /**
      * An invalid value for {@link #rtldDefault}.
@@ -504,14 +429,14 @@
 
     public final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags");
     public final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*");
-    public final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, isJDK8 ? "u1" : "u2");
-    public final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, isJDK8 ? "u1" : "u2");
+    public final int methodIntrinsicIdOffset = versioned.methodIntrinsicIdOffset;
+    public final int methodFlagsOffset = versioned.methodFlagsOffset;
     public final int methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int");
 
     public final int methodCountersOffset = getFieldOffset("Method::_method_counters", Integer.class, "MethodCounters*");
     public final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*");
     public final int methodCompiledEntryOffset = getFieldOffset("Method::_from_compiled_entry", Integer.class, "address");
-    public final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, isJDK8 ? "nmethod*" : "CompiledMethod*");
+    public final int methodCodeOffset = versioned.methodCodeOffset;
 
     public final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
     public final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
@@ -522,8 +447,8 @@
 
     public final int invocationCounterOffset = getFieldOffset("MethodCounters::_invocation_counter", Integer.class, "InvocationCounter");
     public final int backedgeCounterOffset = getFieldOffset("MethodCounters::_backedge_counter", Integer.class, "InvocationCounter");
-    public final int invocationCounterIncrement = getConstant("InvocationCounter::count_increment", Integer.class, intNotPresentInJDK8);
-    public final int invocationCounterShift = getConstant("InvocationCounter::count_shift", Integer.class, intNotPresentInJDK8);
+    public final int invocationCounterIncrement = versioned.invocationCounterIncrement;
+    public final int invocationCounterShift = versioned.invocationCounterShift;
 
     public final int nmethodEntryOffset = getFieldOffset("nmethod::_verified_entry_point",
                     Integer.class, "address");
@@ -548,11 +473,6 @@
 
     public final int logOfHRGrainBytes = getFieldValue("HeapRegion::LogOfHRGrainBytes", Integer.class, "int");
 
-    public final byte dirtyCardValue = jdkVersion >= 11 ? getConstant("CardTable::dirty_card", Byte.class)
-                    : (jdkVersion > 8 ? getConstant("CardTableModRefBS::dirty_card", Byte.class) : getFieldValue("CompilerToVM::Data::dirty_card", Byte.class, "int"));
-    public final byte g1YoungCardValue = jdkVersion >= 11 ? getConstant("G1CardTable::g1_young_gen", Byte.class)
-                    : (jdkVersion > 8 ? getConstant("G1SATBCardTableModRefBS::g1_young_gen", Byte.class) : getFieldValue("CompilerToVM::Data::g1_young_card", Byte.class, "int"));
-
     public final long cardtableStartAddress = getFieldValue("CompilerToVM::Data::cardtable_start_address", Long.class, "jbyte*");
     public final int cardtableShift = getFieldValue("CompilerToVM::Data::cardtable_shift", Integer.class, "int");
 
@@ -560,17 +480,20 @@
      * This is the largest stack offset encodeable in an OopMapValue. Offsets larger than this will
      * throw an exception during code installation.
      */
-    public final int maxOopMapStackOffset = getFieldValueWithAlternate("CompilerToVM::Data::_max_oop_map_stack_offset", "JVMCIRuntime::max_oop_map_stack_offset", Integer.class, "int");
+    public final int maxOopMapStackOffset = getFieldValue("CompilerToVM::Data::_max_oop_map_stack_offset", Integer.class, "int");
 
     public final long safepointPollingAddress = getFieldValue("os::_polling_page", Long.class, "address");
 
     // G1 Collector Related Values.
 
-    public final int g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class);
-    public final int g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class);
-    public final int g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class);
-    public final int g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class);
-    public final int g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class);
+    public final byte dirtyCardValue = versioned.dirtyCardValue;
+    public final byte g1YoungCardValue = versioned.g1YoungCardValue;
+
+    public final int g1SATBQueueMarkingOffset = versioned.g1SATBQueueMarkingOffset;
+    public final int g1SATBQueueIndexOffset = versioned.g1SATBQueueIndexOffset;
+    public final int g1SATBQueueBufferOffset = versioned.g1SATBQueueBufferOffset;
+    public final int g1CardQueueIndexOffset = versioned.g1CardQueueIndexOffset;
+    public final int g1CardQueueBufferOffset = versioned.g1CardQueueBufferOffset;
 
     public final int klassOffset = getFieldValue("java_lang_Class::_klass_offset", Integer.class, "int");
     public final int arrayKlassOffset = getFieldValue("java_lang_Class::_array_klass_offset", Integer.class, "int");
@@ -636,7 +559,7 @@
     // FIXME This is only temporary until the GC code is changed.
     public final boolean inlineContiguousAllocationSupported = getFieldValue("CompilerToVM::Data::_supports_inline_contig_alloc", Boolean.class);
     public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**");
-    public final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, isJDK8 ? "HeapWord**" : "HeapWord* volatile*");
+    public final long heapTopAddress = versioned.heapTopAddress;
 
     public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false);
 
@@ -646,8 +569,8 @@
     public final long handleDeoptStub = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", Long.class, "address");
     public final long uncommonTrapStub = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", Long.class, "address");
 
-    public final long codeCacheLowBound = getFieldValue(isJDK8 ? "CompilerToVM::Data::CodeCache_low_bound" : "CodeCache::_low_bound", Long.class, "address");
-    public final long codeCacheHighBound = getFieldValue(isJDK8 ? "CompilerToVM::Data::CodeCache_high_bound" : "CodeCache::_high_bound", Long.class, "address");
+    public final long codeCacheLowBound = versioned.codeCacheLowBound;
+    public final long codeCacheHighBound = versioned.codeCacheHighBound;
 
     public final long aescryptEncryptBlockStub = getFieldValue("StubRoutines::_aescrypt_encryptBlock", Long.class, "address");
     public final long aescryptDecryptBlockStub = getFieldValue("StubRoutines::_aescrypt_decryptBlock", Long.class, "address");
@@ -675,7 +598,7 @@
     public final long montgomerySquare = getFieldValue("StubRoutines::_montgomerySquare", Long.class, "address", longRequiredOnAMD64);
     public final long vectorizedMismatch = getFieldValue("StubRoutines::_vectorizedMismatch", Long.class, "address", 0L);
 
-    public final long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address", longNotPresentInJDK8);
+    public final long throwDelayedStackOverflowErrorEntry = versioned.throwDelayedStackOverflowErrorEntry;
 
     public final long jbyteArraycopy = getFieldValue("StubRoutines::_jbyte_arraycopy", Long.class, "address");
     public final long jshortArraycopy = getFieldValue("StubRoutines::_jshort_arraycopy", Long.class, "address");
@@ -718,6 +641,8 @@
     public final long exceptionHandlerForPcAddress = getAddress("JVMCIRuntime::exception_handler_for_pc");
     public final long monitorenterAddress = getAddress("JVMCIRuntime::monitorenter");
     public final long monitorexitAddress = getAddress("JVMCIRuntime::monitorexit");
+    public final long notifyAddress = getAddress("JVMCIRuntime::object_notify", 0L);
+    public final long notifyAllAddress = getAddress("JVMCIRuntime::object_notifyAll", 0L);
     public final long throwAndPostJvmtiExceptionAddress = getAddress("JVMCIRuntime::throw_and_post_jvmti_exception");
     public final long throwKlassExternalNameExceptionAddress = getAddress("JVMCIRuntime::throw_klass_external_name_exception");
     public final long throwClassCastExceptionAddress = getAddress("JVMCIRuntime::throw_class_cast_exception");
@@ -735,7 +660,7 @@
     public final long registerFinalizerAddress = getAddress("SharedRuntime::register_finalizer");
     public final long exceptionHandlerForReturnAddressAddress = getAddress("SharedRuntime::exception_handler_for_return_address");
     public final long osrMigrationEndAddress = getAddress("SharedRuntime::OSR_migration_end");
-    public final long enableStackReservedZoneAddress = getAddress("SharedRuntime::enable_stack_reserved_zone", longNotPresentInJDK8);
+    public final long enableStackReservedZoneAddress = versioned.enableStackReservedZoneAddress;
 
     public final long javaTimeMillisAddress = getAddress("os::javaTimeMillis");
     public final long javaTimeNanosAddress = getAddress("os::javaTimeNanos");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import org.graalvm.compiler.api.replacements.Fold;
+import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
+
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+
+/**
+ * This is a source with different versions for various JDKs.
+ */
+public abstract class GraalHotSpotVMConfigBase extends HotSpotVMConfigAccess {
+
+    GraalHotSpotVMConfigBase(HotSpotVMConfigStore store) {
+        super(store);
+        assert this instanceof GraalHotSpotVMConfig;
+        versioned = new GraalHotSpotVMConfigVersioned(store);
+    }
+
+    /**
+     * Contains values that are different between JDK versions.
+     */
+    protected final GraalHotSpotVMConfigVersioned versioned;
+
+    /**
+     * Sentinel value to use for an {@linkplain InjectedParameter injected}
+     * {@link GraalHotSpotVMConfig} parameter to a {@linkplain Fold foldable} method.
+     */
+    public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null;
+
+    public final String osName = getHostOSName();
+    public final String osArch = getHostArchitectureName();
+    public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
+    public final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
+
+    /**
+     * Gets the host operating system name.
+     */
+    private static String getHostOSName() {
+        String osName = System.getProperty("os.name");
+        switch (osName) {
+            case "Linux":
+                osName = "linux";
+                break;
+            case "SunOS":
+                osName = "solaris";
+                break;
+            case "Mac OS X":
+                osName = "bsd";
+                break;
+            default:
+                // Of course Windows is different...
+                if (osName.startsWith("Windows")) {
+                    osName = "windows";
+                } else {
+                    throw new JVMCIError("Unexpected OS name: " + osName);
+                }
+        }
+        return osName;
+    }
+
+    private static String getHostArchitectureName() {
+        String arch = System.getProperty("os.arch");
+        switch (arch) {
+            case "x86_64":
+                arch = "amd64";
+                break;
+            case "sparcv9":
+                arch = "sparc";
+                break;
+        }
+        return arch;
+    }
+
+    protected final Integer intRequiredOnAMD64 = osArch.equals("amd64") ? null : 0;
+    protected final Long longRequiredOnAMD64 = osArch.equals("amd64") ? null : 0L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+
+/**
+ * This is a source with different versions for various JDKs. When modifying/adding a field in this
+ * class accessed from outside this class, be sure to update the field appropriately in all source
+ * files named {@code GraalHotSpotVMConfigVersioned.java}.
+ *
+ * Fields are grouped according to the most recent JBS issue showing why they are versioned.
+ *
+ * JDK Version: 11+
+ */
+final class GraalHotSpotVMConfigVersioned extends HotSpotVMConfigAccess {
+
+    GraalHotSpotVMConfigVersioned(HotSpotVMConfigStore store) {
+        super(store);
+    }
+
+    // JDK-8073583
+    final boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class);
+
+    // JDK-8075171
+    final boolean inlineNotify = getFlag("InlineNotify", Boolean.class);
+
+    // JDK-8046936
+    final int javaThreadReservedStackActivationOffset = getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address");
+    final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2");
+    final long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address");
+    final long enableStackReservedZoneAddress = getAddress("SharedRuntime::enable_stack_reserved_zone");
+
+    // JDK-8135085
+    final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2");
+
+    // JDK-8151956
+    final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*");
+
+    // JDK-8059606
+    final int invocationCounterIncrement = getConstant("InvocationCounter::count_increment", Integer.class);
+    final int invocationCounterShift = getConstant("InvocationCounter::count_shift", Integer.class);
+
+    // JDK-8195142
+    final byte dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class);
+    final byte g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class);
+
+    // JDK-8201318
+    final int g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class);
+    final int g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class);
+    final int g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class);
+    final int g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class);
+    final int g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class);
+
+    // JDK-8033552
+    final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, "HeapWord* volatile*");
+
+    // JDK-8015774
+    final long codeCacheLowBound = getFieldValue("CodeCache::_low_bound", Long.class, "address");
+    final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class, "address");
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Tue Apr 24 09:04:57 2018 -0700
@@ -64,11 +64,11 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.tiers.SuitesProvider;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.word.Pointer;
 
 import jdk.vm.ci.code.CompilationRequest;
 import jdk.vm.ci.code.CompiledCode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -221,6 +221,10 @@
             List<Site> sourcePositionSites = new ArrayList<>();
             for (SourceMapping source : target.getSourceMappings()) {
                 NodeSourcePosition sourcePosition = source.getSourcePosition();
+                if (sourcePosition.isPlaceholder() || sourcePosition.isSubstitution()) {
+                    // HotSpot doesn't understand any of the special positions so just drop them.
+                    continue;
+                }
                 assert sourcePosition.verify();
                 sourcePosition = sourcePosition.trim();
                 /*
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,7 @@
 
 import java.util.Arrays;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.debug.GraalError;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,7 +27,7 @@
 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
 import org.graalvm.compiler.core.target.Backend;
 import org.graalvm.compiler.hotspot.stubs.Stub;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * The details required to link a HotSpot runtime or stub call.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,13 +25,13 @@
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.target.Backend;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
 import org.graalvm.compiler.hotspot.stubs.Stub;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.CallingConvention.Type;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,9 +38,9 @@
 import org.graalvm.compiler.core.GraalCompiler;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.util.CompilationAlarm;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Activation;
+import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.hotspot.CompilationCounters.Options;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -105,17 +105,16 @@
 
     @Override
     public CompilationRequestResult compileMethod(CompilationRequest request) {
-        return compileMethod(request, true);
+        return compileMethod(request, true, graalRuntime.getOptions());
     }
 
     @SuppressWarnings("try")
-    CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault) {
+    CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault, OptionValues options) {
         if (graalRuntime.isShutdown()) {
             return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), false);
         }
 
         ResolvedJavaMethod method = request.getMethod();
-        OptionValues options = graalRuntime.getOptions(method);
 
         if (graalRuntime.isBootstrapping()) {
             if (DebugOptions.BootstrapInitializeOnly.getValue(options)) {
@@ -282,13 +281,6 @@
         return suite;
     }
 
-    public Object mbean() {
-        if (graalRuntime instanceof HotSpotGraalRuntime) {
-            return ((HotSpotGraalRuntime) graalRuntime).getMBean();
-        }
-        return null;
-    }
-
     /**
      * Converts {@code method} to a String with {@link JavaMethod#format(String)} and the format
      * string {@code "%H.%n(%p)"}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,9 +26,8 @@
 import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
 
 import java.io.PrintStream;
-import java.util.Collections;
-import java.util.Map;
 
+import org.graalvm.compiler.api.runtime.GraalRuntime;
 import org.graalvm.compiler.debug.MethodFilter;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
@@ -36,7 +35,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.options.OptionsParser;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
 
 import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
@@ -49,21 +47,7 @@
     private static MethodFilter[] graalCompileOnlyFilter;
     private static boolean compileGraalWithC1Only;
 
-    /**
-     * Module containing {@link HotSpotJVMCICompilerFactory}.
-     */
-    private Object jvmciModule;
-
-    /**
-     * Module containing {@link HotSpotGraalCompilerFactory}.
-     */
-    private Object graalModule;
-
-    /**
-     * Module containing the {@linkplain CompilerConfigurationFactory#selectFactory selected}
-     * configuration.
-     */
-    private Object compilerConfigurationModule;
+    private IsGraalPredicate isGraalPredicate;
 
     private final HotSpotGraalJVMCIServiceLocator locator;
 
@@ -87,10 +71,7 @@
         assert options == null : "cannot select " + getClass() + " service more than once";
         options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
         initializeGraalCompilePolicyFields(options);
-        if (!JDK9Method.Java8OrEarlier) {
-            jvmciModule = JDK9Method.getModule(HotSpotJVMCICompilerFactory.class);
-            graalModule = JDK9Method.getModule(HotSpotGraalCompilerFactory.class);
-        }
+        isGraalPredicate = compileGraalWithC1Only ? new IsGraalPredicate() : null;
         /*
          * Exercise this code path early to encourage loading now. This doesn't solve problem of
          * deadlock during class loading but seems to eliminate it in practice.
@@ -134,10 +115,10 @@
     @Override
     public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) {
         CompilerConfigurationFactory factory = CompilerConfigurationFactory.selectFactory(null, options);
-        if (!JDK9Method.Java8OrEarlier) {
-            compilerConfigurationModule = JDK9Method.getModule(factory.getClass());
+        if (isGraalPredicate != null) {
+            isGraalPredicate.onCompilerConfigurationFactorySelection(factory);
         }
-        HotSpotGraalCompiler compiler = createCompiler(runtime, options, factory);
+        HotSpotGraalCompiler compiler = createCompiler("VM", runtime, options, factory);
         // Only the HotSpotGraalRuntime associated with the compiler created via
         // jdk.vm.ci.runtime.JVMCIRuntime.getCompiler() is registered for receiving
         // VM events.
@@ -149,14 +130,17 @@
      * Creates a new {@link HotSpotGraalRuntime} object and a new {@link HotSpotGraalCompiler} and
      * returns the latter.
      *
+     * @param runtimeNameQualifier a qualifier to be added to the {@linkplain GraalRuntime#getName()
+     *            name} of the {@linkplain HotSpotGraalCompiler#getGraalRuntime() runtime} created
+     *            by this method
      * @param runtime the JVMCI runtime on which the {@link HotSpotGraalRuntime} is built
      * @param compilerConfigurationFactory factory for the {@link CompilerConfiguration}
      */
     @SuppressWarnings("try")
-    public static HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime, OptionValues options, CompilerConfigurationFactory compilerConfigurationFactory) {
+    public static HotSpotGraalCompiler createCompiler(String runtimeNameQualifier, JVMCIRuntime runtime, OptionValues options, CompilerConfigurationFactory compilerConfigurationFactory) {
         HotSpotJVMCIRuntime jvmciRuntime = (HotSpotJVMCIRuntime) runtime;
         try (InitTimer t = timer("HotSpotGraalRuntime.<init>")) {
-            HotSpotGraalRuntime graalRuntime = new HotSpotGraalRuntime(jvmciRuntime, compilerConfigurationFactory, options);
+            HotSpotGraalRuntime graalRuntime = new HotSpotGraalRuntime(runtimeNameQualifier, jvmciRuntime, compilerConfigurationFactory, options);
             return new HotSpotGraalCompiler(jvmciRuntime, graalRuntime, graalRuntime.getOptions());
         }
     }
@@ -187,54 +171,11 @@
         assert HotSpotGraalCompilerFactory.class.getName().equals("org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory");
     }
 
-    static final ClassLoader JVMCI_LOADER = HotSpotGraalCompilerFactory.class.getClassLoader();
-
-    /*
-     * This method is static so it can be exercised during initialization.
-     */
     private CompilationLevel adjustCompilationLevelInternal(Class<?> declaringClass, String name, String signature, CompilationLevel level) {
         if (compileGraalWithC1Only) {
             if (level.ordinal() > CompilationLevel.Simple.ordinal()) {
-                if (JDK9Method.Java8OrEarlier) {
-                    if (JVMCI_LOADER != null) {
-                        // When running with +UseJVMCIClassLoader all classes in
-                        // the JVMCI loader should be compiled with C1.
-                        try {
-                            if (declaringClass.getClassLoader() == JVMCI_LOADER) {
-                                return CompilationLevel.Simple;
-                            }
-                        } catch (SecurityException e) {
-                            // This is definitely not a JVMCI or Graal class
-                        }
-                    } else {
-                        // JVMCI and Graal are on the bootclasspath so match based on the package.
-                        String declaringClassName = declaringClass.getName();
-                        if (declaringClassName.startsWith("jdk.vm.ci")) {
-                            return CompilationLevel.Simple;
-                        }
-                        if (declaringClassName.startsWith("org.graalvm.") &&
-                                        (declaringClassName.startsWith("org.graalvm.compiler.") ||
-                                                        declaringClassName.startsWith("org.graalvm.collections.") ||
-                                                        declaringClassName.startsWith("org.graalvm.compiler.word.") ||
-                                                        declaringClassName.startsWith("org.graalvm.graphio."))) {
-                            return CompilationLevel.Simple;
-                        }
-                        if (declaringClassName.startsWith("com.oracle.graal") &&
-                                        (declaringClassName.startsWith("com.oracle.graal.enterprise") ||
-                                                        declaringClassName.startsWith("com.oracle.graal.vector") ||
-                                                        declaringClassName.startsWith("com.oracle.graal.asm"))) {
-                            return CompilationLevel.Simple;
-                        }
-                    }
-                } else {
-                    try {
-                        Object module = JDK9Method.getModule(declaringClass);
-                        if (jvmciModule == module || graalModule == module || compilerConfigurationModule == module) {
-                            return CompilationLevel.Simple;
-                        }
-                    } catch (Throwable e) {
-                        throw new InternalError(e);
-                    }
+                if (isGraalPredicate.apply(declaringClass)) {
+                    return CompilationLevel.Simple;
                 }
             }
         }
@@ -258,11 +199,4 @@
         }
         return level;
     }
-
-    public Map<String, Object> mbeans() {
-        HotSpotGraalCompiler compiler = createCompiler(HotSpotJVMCIRuntime.runtime());
-        String name = "org.graalvm.compiler.hotspot:type=Options";
-        Object bean = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMBean();
-        return Collections.singletonMap(name, bean);
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
-import jdk.vm.ci.meta.MetaUtil;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.runtime.JVMCI;
-
-import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.options.OptionDescriptor;
-import org.graalvm.compiler.options.OptionDescriptors;
-import org.graalvm.compiler.options.OptionKey;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.options.OptionsParser;
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-
-public final class HotSpotGraalMBean implements javax.management.DynamicMBean {
-    private static Object mBeanServerField;
-    private final HotSpotGraalCompiler compiler;
-    private final OptionValues options;
-    private final EconomicMap<OptionKey<?>, Object> changes;
-    private final EconomicSet<Dump> methodDumps;
-    private volatile EconomicSet<Reference<ClassLoader>> loaders;
-    private javax.management.ObjectName registered;
-    private OptionValues cachedOptions;
-
-    private HotSpotGraalMBean(HotSpotGraalCompiler compiler, OptionValues options) {
-        this.compiler = compiler;
-        this.options = options;
-        this.changes = EconomicMap.create();
-        this.methodDumps = EconomicSet.create();
-        EconomicSet<Reference<ClassLoader>> systemLoaderSet = EconomicSet.create(RefEquivalence.INSTANCE);
-        systemLoaderSet.add(new WeakReference<>(ClassLoader.getSystemClassLoader()));
-        this.loaders = systemLoaderSet;
-    }
-
-    private static boolean isMXServerOn() {
-        if (mBeanServerField == null) {
-            try {
-                final Field field = java.lang.management.ManagementFactory.class.getDeclaredField("platformMBeanServer");
-                field.setAccessible(true);
-                mBeanServerField = field;
-            } catch (Exception ex) {
-                mBeanServerField = java.lang.management.ManagementFactory.class;
-            }
-        }
-        if (mBeanServerField instanceof Field) {
-            try {
-                return ((Field) mBeanServerField).get(null) != null;
-            } catch (Exception ex) {
-                return true;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    public static HotSpotGraalMBean create(HotSpotGraalCompiler compiler) {
-        OptionValues options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
-        HotSpotGraalMBean mbean = new HotSpotGraalMBean(compiler, options);
-        return mbean;
-    }
-
-    public javax.management.ObjectName ensureRegistered(boolean check) {
-        for (int cnt = 0;; cnt++) {
-            if (registered != null) {
-                return registered;
-            }
-            if (check && !isMXServerOn()) {
-                return null;
-            }
-            try {
-                javax.management.MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer();
-                javax.management.ObjectName name = new javax.management.ObjectName("org.graalvm.compiler.hotspot:type=Options" + (cnt == 0 ? "" : cnt));
-                mbs.registerMBean(this, name);
-                registered = name;
-                break;
-            } catch (javax.management.MalformedObjectNameException | javax.management.MBeanRegistrationException | javax.management.NotCompliantMBeanException ex) {
-                throw new IllegalStateException(ex);
-            } catch (javax.management.InstanceAlreadyExistsException ex) {
-                continue;
-            }
-        }
-        return registered;
-    }
-
-    public OptionValues optionsFor(OptionValues initialValues, ResolvedJavaMethod forMethod) {
-        ensureRegistered(true);
-        if (forMethod instanceof HotSpotResolvedJavaMethod) {
-            HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) forMethod).getDeclaringClass();
-            if (type instanceof HotSpotResolvedJavaType) {
-                Class<?> clazz = ((HotSpotResolvedJavaType) type).mirror();
-                Reference<ClassLoader> addNewRef = new WeakReference<>(clazz.getClassLoader());
-                if (!loaders.contains(addNewRef)) {
-                    EconomicSet<Reference<ClassLoader>> newLoaders = EconomicSet.create(RefEquivalence.INSTANCE, loaders);
-                    newLoaders.add(addNewRef);
-                    this.loaders = newLoaders;
-                }
-            }
-        }
-        return currentMap(initialValues, forMethod);
-    }
-
-    private OptionValues currentMap(OptionValues initialValues, ResolvedJavaMethod method) {
-        if (changes.isEmpty() && methodDumps.isEmpty()) {
-            return initialValues;
-        }
-        OptionValues current = cachedOptions;
-        if (current == null) {
-            current = new OptionValues(initialValues, changes);
-            cachedOptions = current;
-        }
-        if (method != null) {
-            for (Dump request : methodDumps) {
-                final String clazzName = method.getDeclaringClass().getName();
-                if (method.getName().equals(request.method) && clazzName.equals(request.clazz)) {
-                    current = new OptionValues(current, DebugOptions.Dump, request.filter,
-                                    DebugOptions.PrintGraphHost, request.host,
-                                    DebugOptions.PrintBinaryGraphPort, request.port);
-                    break;
-                }
-            }
-        }
-        return current;
-    }
-
-    @Override
-    public Object getAttribute(String attribute) {
-        UnmodifiableEconomicMap<OptionKey<?>, Object> map = currentMap(options, null).getMap();
-        for (OptionKey<?> k : map.getKeys()) {
-            if (k.getName().equals(attribute)) {
-                return map.get(k);
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void setAttribute(javax.management.Attribute attribute) throws javax.management.AttributeNotFoundException {
-        javax.management.Attribute newAttr = setImpl(attribute);
-        if (newAttr == null) {
-            throw new javax.management.AttributeNotFoundException();
-        }
-    }
-
-    private javax.management.Attribute setImpl(javax.management.Attribute attribute) {
-        cachedOptions = null;
-        for (OptionDescriptor option : allOptionDescriptors()) {
-            if (option.getName().equals(attribute.getName())) {
-                changes.put(option.getOptionKey(), attribute.getValue());
-                return attribute;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public javax.management.AttributeList getAttributes(String[] names) {
-        javax.management.AttributeList list = new javax.management.AttributeList();
-        for (String name : names) {
-            Object value = getAttribute(name);
-            if (value != null) {
-                list.add(new javax.management.Attribute(name, value));
-            }
-        }
-        return list;
-    }
-
-    @Override
-    public javax.management.AttributeList setAttributes(javax.management.AttributeList attributes) {
-        javax.management.AttributeList setOk = new javax.management.AttributeList();
-        for (javax.management.Attribute attr : attributes.asList()) {
-            javax.management.Attribute newAttr = setImpl(attr);
-            if (newAttr != null) {
-                setOk.add(newAttr);
-            }
-        }
-        return setOk;
-    }
-
-    @Override
-    public Object invoke(String actionName, Object[] params, String[] signature) throws javax.management.MBeanException, javax.management.ReflectionException {
-        if ("dumpMethod".equals(actionName)) {
-            try {
-                String className = param(params, 0, "className", String.class, null);
-                String methodName = param(params, 1, "methodName", String.class, null);
-                String filter = param(params, 2, "filter", String.class, ":3");
-                String host = param(params, 3, "host", String.class, "localhost");
-                Number port = param(params, 4, "port", Number.class, 4445);
-                dumpMethod(className, methodName, filter, host, port.intValue());
-            } catch (Exception ex) {
-                throw new javax.management.ReflectionException(ex);
-            }
-        }
-        return null;
-    }
-
-    private static <T> T param(Object[] arr, int index, String name, Class<T> type, T defaultValue) {
-        Object value = arr.length > index ? arr[index] : null;
-        if (value == null || (value instanceof String && ((String) value).isEmpty())) {
-            if (defaultValue == null) {
-                throw new IllegalArgumentException(name + " must be specified");
-            }
-            value = defaultValue;
-        }
-        if (type.isInstance(value)) {
-            return type.cast(value);
-        }
-        throw new IllegalArgumentException("Expecting " + type.getName() + " for " + name + " but was " + value);
-    }
-
-    public void dumpMethod(String className, String methodName, String filter, String host, int port) throws javax.management.MBeanException {
-        String jvmName = MetaUtil.toInternalName(className);
-        methodDumps.add(new Dump(host, port, jvmName, methodName, filter));
-
-        ClassNotFoundException last = null;
-        EconomicSet<Class<?>> found = EconomicSet.create();
-        Iterator<Reference<ClassLoader>> it = loaders.iterator();
-        while (it.hasNext()) {
-            Reference<ClassLoader> ref = it.next();
-            ClassLoader loader = ref.get();
-            if (loader == null) {
-                it.remove();
-                continue;
-            }
-            try {
-                Class<?> clazz = Class.forName(className, false, loader);
-                if (found.add(clazz)) {
-                    ResolvedJavaType type = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(clazz);
-                    if (compiler != null) {
-                        for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
-                            if (methodName.equals(method.getName()) && method instanceof HotSpotResolvedJavaMethod) {
-                                HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method;
-                                compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false);
-                            }
-                        }
-                    }
-                }
-            } catch (ClassNotFoundException ex) {
-                last = ex;
-            }
-        }
-        if (found.isEmpty()) {
-            throw new javax.management.MBeanException(last, "Cannot find class " + className + " to schedule recompilation");
-        }
-    }
-
-    @Override
-    public javax.management.MBeanInfo getMBeanInfo() {
-        List<javax.management.MBeanAttributeInfo> attrs = new ArrayList<>();
-        for (OptionDescriptor descr : allOptionDescriptors()) {
-            attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
-        }
-        javax.management.MBeanOperationInfo[] ops = {
-                        new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
-                                        new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
-                                        new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
-                        }, "void", javax.management.MBeanOperationInfo.ACTION),
-                        new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
-                                        new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
-                                        new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
-                                        new javax.management.MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
-                        }, "void", javax.management.MBeanOperationInfo.ACTION),
-                        new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
-                                        new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
-                                        new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
-                                        new javax.management.MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
-                                        new javax.management.MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
-                                        new javax.management.MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
-                        }, "void", javax.management.MBeanOperationInfo.ACTION)
-        };
-
-        return new javax.management.MBeanInfo(
-                        HotSpotGraalMBean.class.getName(),
-                        "Graal",
-                        attrs.toArray(new javax.management.MBeanAttributeInfo[attrs.size()]),
-                        null, ops, null);
-    }
-
-    private static Iterable<OptionDescriptor> allOptionDescriptors() {
-        List<OptionDescriptor> arr = new ArrayList<>();
-        for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
-            for (OptionDescriptor descr : set) {
-                arr.add(descr);
-            }
-        }
-        return arr;
-    }
-
-    private static final class Dump {
-        final String host;
-        final int port;
-        final String clazz;
-        final String method;
-        final String filter;
-
-        Dump(String host, int port, String clazz, String method, String filter) {
-            this.host = host;
-            this.port = port;
-            this.clazz = clazz;
-            this.method = method;
-            this.filter = filter;
-        }
-    }
-
-    private static final class RefEquivalence extends Equivalence {
-        static final Equivalence INSTANCE = new RefEquivalence();
-
-        private RefEquivalence() {
-        }
-
-        @Override
-        public boolean equals(Object a, Object b) {
-            Reference<?> refA = (Reference<?>) a;
-            Reference<?> refB = (Reference<?>) b;
-            return Objects.equals(refA.get(), refB.get());
-        }
-
-        @Override
-        public int hashCode(Object o) {
-            Reference<?> ref = (Reference<?>) o;
-            Object obj = ref.get();
-            return obj == null ? 0 : obj.hashCode();
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+/**
+ * Communicates with an MBean providing a JMX interface to a {@link HotSpotGraalRuntime} instance.
+ * The MBean will be dynamically created when a JMX client attaches or some other event causes the
+ * platform MBean server to be started.
+ */
+public interface HotSpotGraalManagementRegistration {
+
+    /**
+     * Completes the initialization of this registration by recording the
+     * {@link HotSpotGraalRuntime} the MBean will provide an JMX interface to.
+     */
+    void initialize(HotSpotGraalRuntime runtime);
+
+    /**
+     * Polls this registration to see if the MBean is registered in a MBean server.
+     *
+     * @param sync synchronize with other threads that may be processing this registration. This is
+     *            useful when the caller knows the server is active (e.g., it has a reference to
+     *            server) and expects this poll to therefore return a non-null value.
+     * @return an {@link javax.management.ObjectName} that can be used to access the MBean or
+     *         {@code null} if the MBean has not been registered with an MBean server (e.g., no JMX
+     *         client has attached to the VM)
+     */
+    Object poll(boolean sync);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,14 +30,12 @@
 import java.util.Map;
 import java.util.Properties;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionDescriptors;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.options.OptionValuesAccess;
 import org.graalvm.compiler.options.OptionsParser;
-import org.graalvm.compiler.serviceprovider.ServiceProvider;
 
 import jdk.vm.ci.common.InitTimer;
 
@@ -45,8 +43,7 @@
  * The {@link #HOTSPOT_OPTIONS} value contains the options values initialized in a HotSpot VM. The
  * values are set via system properties with the {@value #GRAAL_OPTION_PROPERTY_PREFIX} prefix.
  */
-@ServiceProvider(OptionValuesAccess.class)
-public class HotSpotGraalOptionValues implements OptionValuesAccess {
+public class HotSpotGraalOptionValues {
 
     /**
      * The name of the system property specifying a file containing extra Graal option settings.
@@ -131,9 +128,4 @@
             return new OptionValues(values);
         }
     }
-
-    @Override
-    public OptionValues getOptions() {
-        return HOTSPOT_OPTIONS;
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,9 +33,12 @@
 import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.api.runtime.GraalRuntime;
 import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
@@ -45,6 +48,7 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Description;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
 import org.graalvm.compiler.debug.GlobalMetrics;
 import org.graalvm.compiler.debug.GraalError;
@@ -54,19 +58,31 @@
 import org.graalvm.compiler.hotspot.debug.BenchmarkCounters;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
 import org.graalvm.compiler.nodes.spi.StampProvider;
+import org.graalvm.compiler.options.EnumOptionKey;
+import org.graalvm.compiler.options.OptionDescriptor;
+import org.graalvm.compiler.options.OptionDescriptors;
+import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.options.OptionsParser;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.replacements.SnippetCounter;
 import org.graalvm.compiler.replacements.SnippetCounter.Group;
 import org.graalvm.compiler.runtime.RuntimeProvider;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.stack.StackIntrospection;
 import jdk.vm.ci.common.InitTimer;
+import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.runtime.JVMCIBackend;
 
 //JaCoCo Exclude
@@ -88,6 +104,7 @@
         return true;
     }
 
+    private final String runtimeName;
     private final HotSpotBackend hostBackend;
     private final GlobalMetrics metricValues = new GlobalMetrics();
     private final List<SnippetCounter.Group> snippetCounterGroups;
@@ -96,25 +113,42 @@
 
     private final GraalHotSpotVMConfig config;
 
-    private final OptionValues options;
+    /**
+     * The options can be {@linkplain #setOptionValues(String[], String[]) updated} by external
+     * interfaces such as JMX. This comes with the risk that inconsistencies can arise as an
+     * {@link OptionValues} object can be cached by various parts of Graal instead of always
+     * obtaining them from this object. However, concurrent updates are never lost.
+     */
+    private AtomicReference<OptionValues> optionsRef = new AtomicReference<>();
+
+    private final HotSpotGraalCompiler compiler;
+
     private final DiagnosticsOutputDirectory outputDirectory;
     private final Map<ExceptionAction, Integer> compilationProblemsPerAction;
-    private final HotSpotGraalMBean mBean;
 
     /**
+     * @param nameQualifier a qualifier to be added to this runtime's {@linkplain #getName() name}
      * @param compilerConfigurationFactory factory for the compiler configuration
      *            {@link CompilerConfigurationFactory#selectFactory(String, OptionValues)}
      */
     @SuppressWarnings("try")
-    HotSpotGraalRuntime(HotSpotJVMCIRuntime jvmciRuntime, CompilerConfigurationFactory compilerConfigurationFactory, OptionValues initialOptions) {
+    HotSpotGraalRuntime(String nameQualifier, HotSpotJVMCIRuntime jvmciRuntime, CompilerConfigurationFactory compilerConfigurationFactory, OptionValues initialOptions) {
+        this.runtimeName = getClass().getSimpleName() + ":" + nameQualifier;
         HotSpotVMConfigStore store = jvmciRuntime.getConfigStore();
         config = GeneratePIC.getValue(initialOptions) ? new AOTGraalHotSpotVMConfig(store) : new GraalHotSpotVMConfig(store);
 
         // Only set HotSpotPrintInlining if it still has its default value (false).
         if (GraalOptions.HotSpotPrintInlining.getValue(initialOptions) == false && config.printInlining) {
-            options = new OptionValues(initialOptions, HotSpotPrintInlining, true);
+            optionsRef.set(new OptionValues(initialOptions, HotSpotPrintInlining, true));
         } else {
-            options = initialOptions;
+            optionsRef.set(initialOptions);
+        }
+        OptionValues options = optionsRef.get();
+
+        if (config.useCMSGC) {
+            // Graal doesn't work with the CMS collector (e.g. GR-6777)
+            // and is deprecated (http://openjdk.java.net/jeps/291).
+            throw new GraalError("Graal does not support the CMS collector");
         }
 
         outputDirectory = new DiagnosticsOutputDirectory(options);
@@ -122,8 +156,11 @@
         snippetCounterGroups = GraalOptions.SnippetCounters.getValue(options) ? new ArrayList<>() : null;
         CompilerConfiguration compilerConfiguration = compilerConfigurationFactory.createCompilerConfiguration();
 
-        HotSpotGraalCompiler compiler = new HotSpotGraalCompiler(jvmciRuntime, this, initialOptions);
-        this.mBean = createHotSpotGraalMBean(compiler);
+        compiler = new HotSpotGraalCompiler(jvmciRuntime, this, options);
+        management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false);
+        if (management != null) {
+            management.initialize(this);
+        }
 
         BackendMap backendMap = compilerConfigurationFactory.createBackendMap();
 
@@ -172,14 +209,6 @@
         bootstrapJVMCI = config.getFlag("BootstrapJVMCI", Boolean.class);
     }
 
-    private static HotSpotGraalMBean createHotSpotGraalMBean(HotSpotGraalCompiler compiler) {
-        try {
-            return HotSpotGraalMBean.create(compiler);
-        } catch (LinkageError ex) {
-            return null;
-        }
-    }
-
     private HotSpotBackend registerBackend(HotSpotBackend backend) {
         Class<? extends Architecture> arch = backend.getTarget().arch.getClass();
         HotSpotBackend oldValue = backends.put(arch, backend);
@@ -199,24 +228,35 @@
 
     @Override
     public DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories) {
+        if (management != null && management.poll(false) != null) {
+            if (compilable instanceof HotSpotResolvedJavaMethod) {
+                HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) compilable).getDeclaringClass();
+                if (type instanceof HotSpotResolvedJavaType) {
+                    Class<?> clazz = ((HotSpotResolvedJavaType) type).mirror();
+                    try {
+                        ClassLoader cl = clazz.getClassLoader();
+                        if (cl != null) {
+                            loaders.add(cl);
+                        }
+                    } catch (SecurityException e) {
+                        // This loader can obviously not be used for resolving class names
+                    }
+                }
+            }
+        }
         Description description = new Description(compilable, compilationId.toString(CompilationIdentifier.Verbosity.ID));
         return DebugContext.create(compilationOptions, description, metricValues, DEFAULT_LOG_STREAM, factories);
     }
 
     @Override
     public OptionValues getOptions() {
-        return mBean == null ? options : mBean.optionsFor(options, null);
+        return optionsRef.get();
     }
 
     @Override
-    public OptionValues getOptions(ResolvedJavaMethod forMethod) {
-        return mBean == null ? options : mBean.optionsFor(options, forMethod);
-    }
-
-    @Override
-    public Group createSnippetCounterGroup(String name) {
+    public Group createSnippetCounterGroup(String groupName) {
         if (snippetCounterGroups != null) {
-            Group group = new Group(name);
+            Group group = new Group(groupName);
             snippetCounterGroups.add(group);
             return group;
         }
@@ -225,7 +265,7 @@
 
     @Override
     public String getName() {
-        return getClass().getSimpleName();
+        return runtimeName;
     }
 
     @SuppressWarnings("unchecked")
@@ -234,7 +274,7 @@
         if (clazz == RuntimeProvider.class) {
             return (T) this;
         } else if (clazz == OptionValues.class) {
-            return (T) options;
+            return (T) optionsRef.get();
         } else if (clazz == StackIntrospection.class) {
             return (T) this;
         } else if (clazz == SnippetReflectionProvider.class) {
@@ -265,14 +305,14 @@
      * @param phase the execution phase being entered
      */
     void phaseTransition(String phase) {
-        if (Options.UseCompilationStatistics.getValue(options)) {
+        if (Options.UseCompilationStatistics.getValue(optionsRef.get())) {
             CompilationStatistics.clear(phase);
         }
     }
 
     void shutdown() {
         shutdown = true;
-        metricValues.print(options);
+        metricValues.print(optionsRef.get());
 
         phaseTransition("final");
 
@@ -281,7 +321,7 @@
                 TTY.out().out().println(group);
             }
         }
-        BenchmarkCounters.shutdown(runtime(), options, runtimeStartTime);
+        BenchmarkCounters.shutdown(runtime(), optionsRef.get(), runtimeStartTime);
 
         outputDirectory.close();
     }
@@ -317,7 +357,193 @@
         return compilationProblemsPerAction;
     }
 
-    Object getMBean() {
-        return mBean;
+    // ------- Management interface ---------
+
+    private final HotSpotGraalManagementRegistration management;
+
+    /**
+     * @returns the management object for this runtime or {@code null}
+     */
+    public HotSpotGraalManagementRegistration getManagement() {
+        return management;
+    }
+
+    /**
+     * Set of weak references to {@link ClassLoader}s available for resolving class names present in
+     * management {@linkplain #invokeManagementAction(String, Object[]) action} arguments.
+     */
+    private final WeakClassLoaderSet loaders = new WeakClassLoaderSet(ClassLoader.getSystemClassLoader());
+
+    /**
+     * Sets or updates this object's {@linkplain #getOptions() options} from {@code names} and
+     * {@code values}.
+     *
+     * @param values the values to set. The empty string represents {@code null} which resets an
+     *            option to its default value. For string type options, a non-empty value must be
+     *            enclosed in double quotes.
+     * @return an array of Strings where the element at index i is {@code names[i]} if setting the
+     *         denoted option succeeded, {@code null} if the option is unknown otherwise an error
+     *         message describing the failure to set the option
+     */
+    public String[] setOptionValues(String[] names, String[] values) {
+        EconomicMap<String, OptionDescriptor> optionDescriptors = getOptionDescriptors();
+        EconomicMap<OptionKey<?>, Object> newValues = EconomicMap.create(names.length);
+        EconomicSet<OptionKey<?>> resetValues = EconomicSet.create(names.length);
+        String[] result = new String[names.length];
+        for (int i = 0; i < names.length; i++) {
+            String name = names[i];
+            OptionDescriptor option = optionDescriptors.get(name);
+            if (option != null) {
+                String svalue = values[i];
+                Class<?> optionValueType = option.getOptionValueType();
+                OptionKey<?> optionKey = option.getOptionKey();
+                if (svalue == null || svalue.isEmpty() && !(optionKey instanceof EnumOptionKey)) {
+                    resetValues.add(optionKey);
+                    result[i] = name;
+                } else {
+                    String valueToParse;
+                    if (optionValueType == String.class) {
+                        if (svalue.length() < 2 || svalue.charAt(0) != '"' || svalue.charAt(svalue.length() - 1) != '"') {
+                            result[i] = "Invalid value for String option '" + name + "': must be the empty string or be enclosed in double quotes: " + svalue;
+                            continue;
+                        } else {
+                            valueToParse = svalue.substring(1, svalue.length() - 1);
+                        }
+                    } else {
+                        valueToParse = svalue;
+                    }
+                    try {
+                        OptionsParser.parseOption(name, valueToParse, newValues, OptionsParser.getOptionsLoader());
+                        result[i] = name;
+                    } catch (IllegalArgumentException e) {
+                        result[i] = e.getMessage();
+                        continue;
+                    }
+                }
+            } else {
+                result[i] = null;
+            }
+        }
+
+        OptionValues currentOptions;
+        OptionValues newOptions;
+        do {
+            currentOptions = optionsRef.get();
+            UnmodifiableMapCursor<OptionKey<?>, Object> cursor = currentOptions.getMap().getEntries();
+            while (cursor.advance()) {
+                OptionKey<?> key = cursor.getKey();
+                if (!resetValues.contains(key) && !newValues.containsKey(key)) {
+                    newValues.put(key, OptionValues.decodeNull(cursor.getValue()));
+                }
+            }
+            newOptions = new OptionValues(newValues);
+        } while (!optionsRef.compareAndSet(currentOptions, newOptions));
+
+        return result;
+    }
+
+    /**
+     * Gets the values for the options corresponding to {@code names} encoded as strings. The empty
+     * string represents {@code null}. For string type options, non-{@code null} values will be
+     * enclosed in double quotes.
+     *
+     * @param names a list of option names
+     * @return the values for each named option. If an element in {@code names} does not denote an
+     *         existing option, the corresponding element in the returned array will be {@code null}
+     */
+    public String[] getOptionValues(String... names) {
+        String[] values = new String[names.length];
+        EconomicMap<String, OptionDescriptor> optionDescriptors = getOptionDescriptors();
+        for (int i = 0; i < names.length; i++) {
+            OptionDescriptor option = optionDescriptors.get(names[i]);
+            if (option != null) {
+                OptionKey<?> optionKey = option.getOptionKey();
+                Object value = optionKey.getValue(getOptions());
+                String svalue;
+                if (option.getOptionValueType() == String.class && value != null) {
+                    svalue = "\"" + value + "\"";
+                } else if (value == null) {
+                    svalue = "";
+                } else {
+                    svalue = String.valueOf(value);
+                }
+                values[i] = svalue;
+            } else {
+                // null denotes the option does not exist
+                values[i] = null;
+            }
+        }
+        return values;
+    }
+
+    private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() {
+        EconomicMap<String, OptionDescriptor> result = EconomicMap.create();
+        for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
+            for (OptionDescriptor option : set) {
+                result.put(option.getName(), option);
+            }
+        }
+        return result;
+    }
+
+    private void dumpMethod(String className, String methodName, String filter, String host, int port) throws Exception {
+        EconomicSet<ClassNotFoundException> failures = EconomicSet.create();
+        EconomicSet<Class<?>> found = loaders.resolve(className, failures);
+        if (found.isEmpty()) {
+            ClassNotFoundException cause = failures.isEmpty() ? new ClassNotFoundException(className) : failures.iterator().next();
+            throw new Exception("Cannot find class " + className + " to schedule recompilation", cause);
+        }
+        for (Class<?> clazz : found) {
+            ResolvedJavaType type = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(clazz);
+            for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+                if (methodName.equals(method.getName()) && method instanceof HotSpotResolvedJavaMethod) {
+                    HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method;
+                    dumpMethod(hotSpotMethod, filter, host, port);
+                }
+            }
+        }
+    }
+
+    private void dumpMethod(HotSpotResolvedJavaMethod hotSpotMethod, String filter, String host, int port) throws Exception {
+        EconomicMap<OptionKey<?>, Object> extra = EconomicMap.create();
+        extra.put(DebugOptions.Dump, filter);
+        extra.put(DebugOptions.PrintGraphHost, host);
+        extra.put(DebugOptions.PrintBinaryGraphPort, port);
+        OptionValues compileOptions = new OptionValues(getOptions(), extra);
+        compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false, compileOptions);
+    }
+
+    public Object invokeManagementAction(String actionName, Object[] params) throws Exception {
+        if ("dumpMethod".equals(actionName)) {
+            if (params.length != 0 && params[0] instanceof HotSpotResolvedJavaMethod) {
+                HotSpotResolvedJavaMethod method = param(params, 0, "method", HotSpotResolvedJavaMethod.class, null);
+                String filter = param(params, 1, "filter", String.class, ":3");
+                String host = param(params, 2, "host", String.class, "localhost");
+                Number port = param(params, 3, "port", Number.class, 4445);
+                dumpMethod(method, filter, host, port.intValue());
+            } else {
+                String className = param(params, 0, "className", String.class, null);
+                String methodName = param(params, 1, "methodName", String.class, null);
+                String filter = param(params, 2, "filter", String.class, ":3");
+                String host = param(params, 3, "host", String.class, "localhost");
+                Number port = param(params, 4, "port", Number.class, 4445);
+                dumpMethod(className, methodName, filter, host, port.intValue());
+            }
+        }
+        return null;
+    }
+
+    private static <T> T param(Object[] arr, int index, String name, Class<T> type, T defaultValue) {
+        Object value = arr.length > index ? arr[index] : null;
+        if (value == null || (value instanceof String && ((String) value).isEmpty())) {
+            if (defaultValue == null) {
+                throw new IllegalArgumentException(name + " must be specified");
+            }
+            value = defaultValue;
+        }
+        if (type.isInstance(value)) {
+            return type.cast(value);
+        }
+        throw new IllegalArgumentException("Expecting " + type.getName() + " for " + name + " but was " + value);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntimeProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntimeProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,16 +27,15 @@
 import org.graalvm.compiler.api.runtime.GraalRuntime;
 import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
-import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.replacements.SnippetCounter.Group;
 import org.graalvm.compiler.runtime.RuntimeProvider;
 
 import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 //JaCoCo Exclude
 
@@ -77,14 +76,6 @@
     OptionValues getOptions();
 
     /**
-     * Gets the option values associated with this runtime that are applicable for a given method.
-     *
-     * @param forMethod the method we are seeking for options for
-     * @return the options applicable for compiling {@code method}
-     */
-    OptionValues getOptions(ResolvedJavaMethod forMethod);
-
-    /**
      * Determines if the VM is currently bootstrapping the JVMCI compiler.
      */
     boolean isBootstrapping();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.hotspot;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.hotspot.stubs.Stub;
 import org.graalvm.compiler.lir.LIR;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
+
+/**
+ * Determines if a given class is a JVMCI or Graal class for the purpose of
+ * {@link HotSpotGraalCompilerFactory.Options#CompileGraalWithC1Only}.
+ */
+public class IsGraalPredicate {
+    /**
+     * Module containing {@link HotSpotJVMCICompilerFactory}.
+     */
+    private final Module jvmciModule;
+
+    /**
+     * Module containing {@link HotSpotGraalCompilerFactory}.
+     */
+    private final Module graalModule;
+
+    /**
+     * Module containing the {@linkplain CompilerConfigurationFactory#selectFactory selected}
+     * configuration.
+     */
+    private Module compilerConfigurationModule;
+
+    public IsGraalPredicate() {
+        jvmciModule = HotSpotJVMCICompilerFactory.class.getModule();
+        graalModule = HotSpotGraalCompilerFactory.class.getModule();
+    }
+
+    void onCompilerConfigurationFactorySelection(CompilerConfigurationFactory factory) {
+        compilerConfigurationModule = factory.getClass().getModule();
+    }
+
+    boolean apply(Class<?> declaringClass) {
+        Module module = declaringClass.getModule();
+        return jvmciModule == module || graalModule == module || compilerConfigurationModule == module;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,15 +27,19 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.util.List;
 
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
 
 /**
- * An option that encapsulates and configures a print stream.
+ * An option for a configurable file name that can also open a {@link PrintStream} on the file. If
+ * no value is given for the option, the stream will output to HotSpot's
+ * {@link HotSpotJVMCIRuntimeProvider#getLogStream() log} stream
  */
 public class PrintStreamOptionKey extends OptionKey<String> {
 
@@ -44,27 +48,13 @@
     }
 
     /**
-     * Replace any instance of %p with an identifying name. Try to get it from the RuntimeMXBean
-     * name.
-     *
-     * @return the name of the file to log to
+     * @return {@code nameTemplate} with all instances of %p replaced by
+     *         {@link GraalServices#getExecutionID()} and %t by {@link System#currentTimeMillis()}
      */
-    private String getFilename(OptionValues options) {
-        String name = getValue(options);
+    private static String makeFilename(String nameTemplate) {
+        String name = nameTemplate;
         if (name.contains("%p")) {
-            try {
-                String runtimeName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
-                int index = runtimeName.indexOf('@');
-                if (index != -1) {
-                    long pid = Long.parseLong(runtimeName.substring(0, index));
-                    runtimeName = Long.toString(pid);
-                }
-                name = name.replaceAll("%p", runtimeName);
-            } catch (NumberFormatException e) {
-
-            } catch (LinkageError err) {
-                name = String.valueOf(org.graalvm.compiler.debug.PathUtilities.getGlobalTimeStamp());
-            }
+            name = name.replaceAll("%p", GraalServices.getExecutionID());
         }
         if (name.contains("%t")) {
             name = name.replaceAll("%t", String.valueOf(System.currentTimeMillis()));
@@ -118,22 +108,26 @@
      * will output to HotSpot's {@link HotSpotJVMCIRuntimeProvider#getLogStream() log} stream.
      */
     public PrintStream getStream(OptionValues options) {
-        if (getValue(options) != null) {
+        String nameTemplate = getValue(options);
+        if (nameTemplate != null) {
+            String name = makeFilename(nameTemplate);
             try {
                 final boolean enableAutoflush = true;
-                PrintStream ps = new PrintStream(new FileOutputStream(getFilename(options)), enableAutoflush);
+                PrintStream ps = new PrintStream(new FileOutputStream(name), enableAutoflush);
                 /*
                  * Add the JVM and Java arguments to the log file to help identity it.
                  */
-                String inputArguments = String.join(" ", java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments());
-                ps.println("VM Arguments: " + inputArguments);
+                List<String> inputArguments = GraalServices.getInputArguments();
+                if (inputArguments != null) {
+                    ps.println("VM Arguments: " + String.join(" ", inputArguments));
+                }
                 String cmd = System.getProperty("sun.java.command");
                 if (cmd != null) {
                     ps.println("sun.java.command=" + cmd);
                 }
                 return ps;
             } catch (FileNotFoundException e) {
-                throw new RuntimeException("couldn't open file: " + getValue(options), e);
+                throw new RuntimeException("couldn't open file: " + name, e);
             }
         } else {
             return new PrintStream(new DelayedOutputStream());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/WeakClassLoaderSet.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.UnaryOperator;
+
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+
+/**
+ * A set of weak references to {@link ClassLoader}s.
+ */
+public final class WeakClassLoaderSet {
+
+    /**
+     * Copy-on-write set of loaders.
+     */
+    private volatile AtomicReference<EconomicSet<Reference<ClassLoader>>> loaders = new AtomicReference<>(EconomicSet.create(RefEquivalence.INSTANCE));
+
+    public WeakClassLoaderSet(ClassLoader... initialEntries) {
+        for (ClassLoader loader : initialEntries) {
+            loaders.get().add(new WeakReference<>(loader));
+        }
+    }
+
+    /**
+     * Adds {@code loader} to this set.
+     */
+    public void add(ClassLoader loader) {
+        Reference<ClassLoader> addNewRef = new WeakReference<>(loader);
+        EconomicSet<Reference<ClassLoader>> currentLoaders = loaders.get();
+        if (!currentLoaders.contains(addNewRef)) {
+            this.loaders.getAndUpdate(new UnaryOperator<EconomicSet<Reference<ClassLoader>>>() {
+                @Override
+                public EconomicSet<Reference<ClassLoader>> apply(EconomicSet<Reference<ClassLoader>> t) {
+                    EconomicSet<Reference<ClassLoader>> newLoaders = EconomicSet.create(RefEquivalence.INSTANCE, t);
+                    newLoaders.add(addNewRef);
+                    return newLoaders;
+                }
+            });
+        }
+    }
+
+    /**
+     * Tries to resolve {@code className} to {@link Class} instances with the loaders in this set.
+     *
+     * @param className name of a class to resolve
+     * @param resolutionFailures all resolution failures are returned in this set
+     * @return the set of classes successfully resolved
+     */
+    public EconomicSet<Class<?>> resolve(String className, EconomicSet<ClassNotFoundException> resolutionFailures) {
+        EconomicSet<Class<?>> found = EconomicSet.create();
+        Iterator<Reference<ClassLoader>> it = loaders.get().iterator();
+        while (it.hasNext()) {
+            Reference<ClassLoader> ref = it.next();
+            ClassLoader loader = ref.get();
+            if (loader == null) {
+                it.remove();
+                continue;
+            }
+            try {
+                Class<?> clazz = Class.forName(className, false, loader);
+                found.add(clazz);
+            } catch (ClassNotFoundException ex) {
+                resolutionFailures.add(ex);
+            }
+        }
+        return found;
+    }
+
+    private static final class RefEquivalence extends Equivalence {
+        static final Equivalence INSTANCE = new RefEquivalence();
+
+        private RefEquivalence() {
+        }
+
+        @Override
+        public boolean equals(Object a, Object b) {
+            Reference<?> refA = (Reference<?>) a;
+            Reference<?> refB = (Reference<?>) b;
+            Object referentA = refA.get();
+            Object referentB = refB.get();
+            return Objects.equals(referentA, referentB);
+        }
+
+        @Override
+        public int hashCode(Object o) {
+            Reference<?> ref = (Reference<?>) o;
+            Object obj = ref.get();
+            return obj == null ? 0 : obj.hashCode();
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.common.AddressLoweringPhase;
+import org.graalvm.compiler.phases.Phase;
 import org.graalvm.compiler.phases.common.ExpandLogicPhase;
 import org.graalvm.compiler.phases.common.FixReadsPhase;
 import org.graalvm.compiler.phases.tiers.LowTierContext;
@@ -41,10 +41,10 @@
  */
 public class AddressLoweringHotSpotSuitesProvider extends HotSpotSuitesProvider {
 
-    private final AddressLoweringPhase.AddressLowering addressLowering;
+    private final Phase addressLowering;
 
     public AddressLoweringHotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime,
-                    AddressLoweringPhase.AddressLowering addressLowering) {
+                    Phase addressLowering) {
         super(defaultSuitesCreator, config, runtime);
         this.addressLowering = addressLowering;
     }
@@ -57,7 +57,7 @@
         if (findPhase == null) {
             findPhase = suites.getLowTier().findPhase(ExpandLogicPhase.class);
         }
-        findPhase.add(new AddressLoweringPhase(addressLowering));
+        findPhase.add(addressLowering);
 
         return suites;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.lang.ref.Reference;
 
@@ -155,7 +155,7 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.replacements.DefaultJavaLoweringProvider;
 import org.graalvm.compiler.replacements.nodes.AssertionNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,7 +30,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
@@ -43,7 +43,7 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.CodeCacheProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_THREAD_OBJECT_LOCATION;
 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MutableCallSite;
@@ -100,10 +100,9 @@
 import org.graalvm.compiler.replacements.ReplacementsImpl;
 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins;
 import org.graalvm.compiler.serviceprovider.GraalServices;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
 import org.graalvm.compiler.word.WordOperationPlugin;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -160,7 +159,7 @@
             @Override
             public void run() {
                 BytecodeProvider replacementBytecodeProvider = replacements.getDefaultReplacementBytecodeProvider();
-                registerObjectPlugins(invocationPlugins, options, replacementBytecodeProvider);
+                registerObjectPlugins(invocationPlugins, options, config, replacementBytecodeProvider);
                 registerClassPlugins(plugins, config, replacementBytecodeProvider);
                 registerSystemPlugins(invocationPlugins, foreignCalls);
                 registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacementBytecodeProvider);
@@ -186,7 +185,7 @@
         return plugins;
     }
 
-    private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, BytecodeProvider bytecodeProvider) {
+    private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
         Registration r = new Registration(plugins, Object.class, bytecodeProvider);
         if (!GeneratePIC.getValue(options)) {
             // FIXME: clone() requires speculation and requires a fix in here (to check that
@@ -210,6 +209,12 @@
             });
         }
         r.registerMethodSubstitution(ObjectSubstitutions.class, "hashCode", Receiver.class);
+        if (config.inlineNotify()) {
+            r.registerMethodSubstitution(ObjectSubstitutions.class, "notify", Receiver.class);
+        }
+        if (config.inlineNotifyAll()) {
+            r.registerMethodSubstitution(ObjectSubstitutions.class, "notifyAll", Receiver.class);
+        }
     }
 
     private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
@@ -440,7 +445,7 @@
     public static final String constantPoolClass;
 
     static {
-        if (JDK9Method.Java8OrEarlier) {
+        if (Java8OrEarlier) {
             cbcEncryptName = "encrypt";
             cbcDecryptName = "decrypt";
             aesEncryptName = "encryptBlock";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -97,11 +97,11 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.util.EnumMap;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.debug.GraalError;
@@ -124,7 +124,7 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
@@ -140,6 +140,9 @@
     public static final ForeignCallDescriptor JAVA_TIME_MILLIS = new ForeignCallDescriptor("javaTimeMillis", long.class);
     public static final ForeignCallDescriptor JAVA_TIME_NANOS = new ForeignCallDescriptor("javaTimeNanos", long.class);
 
+    public static final ForeignCallDescriptor NOTIFY = new ForeignCallDescriptor("object_notify", boolean.class, Object.class);
+    public static final ForeignCallDescriptor NOTIFY_ALL = new ForeignCallDescriptor("object_notifyAll", boolean.class, Object.class);
+
     public HotSpotHostForeignCallsProvider(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache,
                     WordTypes wordTypes) {
         super(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes);
@@ -292,6 +295,8 @@
         linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
         linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any());
         linkForeignCall(options, providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
+        linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
+        linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
         linkForeignCall(options, providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
         linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE, c.dynamicNewInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
         linkForeignCall(options, providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,15 +22,9 @@
  */
 package org.graalvm.compiler.hotspot.meta;
 
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import java.lang.reflect.Type;
 
-import java.lang.invoke.MethodHandle;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.core.common.GraalOptions;
-import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -43,7 +37,6 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.replacements.nodes.MacroNode;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
 
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
 import jdk.vm.ci.meta.JavaKind;
@@ -54,18 +47,11 @@
  */
 final class HotSpotInvocationPlugins extends InvocationPlugins {
     private final GraalHotSpotVMConfig config;
-    private final EconomicSet<Object> trustedModules;
-    private final ClassLoader extLoader;
+    private final IntrinsificationPredicate intrinsificationPredicate;
 
     HotSpotInvocationPlugins(GraalHotSpotVMConfig config, CompilerConfiguration compilerConfiguration) {
         this.config = config;
-        if (Java8OrEarlier) {
-            extLoader = getExtLoader();
-            trustedModules = null;
-        } else {
-            extLoader = null;
-            trustedModules = initTrustedModules(compilerConfiguration);
-        }
+        intrinsificationPredicate = new IntrinsificationPredicate(compilerConfiguration);
     }
 
     @Override
@@ -114,79 +100,12 @@
         return type != null && "Ljava/lang/Class;".equals(type.getName());
     }
 
-    /**
-     * {@inheritDoc}
-     *
-     * On JDK 8, only classes loaded by the boot, JVMCI or extension class loaders are trusted.
-     *
-     * On JDK 9 and later, only classes in the {@link CompilerConfiguration} defining module or any
-     * of its module dependencies are trusted.
-     */
     @Override
     public boolean canBeIntrinsified(ResolvedJavaType declaringClass) {
         if (declaringClass instanceof HotSpotResolvedJavaType) {
-            Class<?> javaClass = ((HotSpotResolvedJavaType) declaringClass).mirror();
-            if (Java8OrEarlier) {
-                ClassLoader cl = javaClass.getClassLoader();
-                return cl == null || cl == getClass().getClassLoader() || cl == extLoader;
-            } else {
-                Object module = JDK9Method.getModule(javaClass);
-                return trustedModules.contains(module);
-            }
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) declaringClass;
+            return intrinsificationPredicate.apply(type.mirror());
         }
         return false;
     }
-
-    private static ClassLoader getExtLoader() {
-        try {
-            Object launcher = Class.forName("sun.misc.Launcher").getMethod("getLauncher").invoke(null);
-            ClassLoader appLoader = (ClassLoader) launcher.getClass().getMethod("getClassLoader").invoke(launcher);
-            ClassLoader extLoader = appLoader.getParent();
-            assert extLoader.getClass().getName().equals("sun.misc.Launcher$ExtClassLoader") : extLoader;
-            return extLoader;
-        } catch (Exception e) {
-            throw new GraalError(e);
-        }
-    }
-
-    /**
-     * Gets the set of modules whose methods can be intrinsified. This set is the module owning the
-     * class of {@code compilerConfiguration} and all its dependencies.
-     */
-    private static EconomicSet<Object> initTrustedModules(CompilerConfiguration compilerConfiguration) throws GraalError {
-        try {
-            EconomicSet<Object> res = EconomicSet.create();
-            Object compilerConfigurationModule = JDK9Method.getModule(compilerConfiguration.getClass());
-            res.add(compilerConfigurationModule);
-            Class<?> moduleClass = compilerConfigurationModule.getClass();
-            Object layer = JDK9Method.lookupMethodHandle(moduleClass, "getLayer").invoke(compilerConfigurationModule);
-            Class<? extends Object> layerClass = layer.getClass();
-            MethodHandle getName = JDK9Method.lookupMethodHandle(moduleClass, "getName");
-            Set<Object> modules = (Set<Object>) JDK9Method.lookupMethodHandle(layerClass, "modules").invoke(layer);
-            Object descriptor = JDK9Method.lookupMethodHandle(moduleClass, "getDescriptor").invoke(compilerConfigurationModule);
-            Class<?> moduleDescriptorClass = descriptor.getClass();
-            Set<Object> requires = (Set<Object>) JDK9Method.lookupMethodHandle(moduleDescriptorClass, "requires").invoke(descriptor);
-            boolean isAutomatic = (Boolean) JDK9Method.lookupMethodHandle(moduleDescriptorClass, "isAutomatic").invoke(descriptor);
-            if (isAutomatic) {
-                throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module",
-                                getName.invoke(compilerConfigurationModule), compilerConfiguration.getClass().getName()));
-            }
-            MethodHandle requireNameGetter = null;
-            for (Object require : requires) {
-                if (requireNameGetter == null) {
-                    requireNameGetter = JDK9Method.lookupMethodHandle(require.getClass(), "name");
-                }
-                String name = (String) requireNameGetter.invoke(require);
-                for (Object module : modules) {
-                    String moduleName = (String) getName.invoke(module);
-                    if (moduleName.equals(name)) {
-                        res.add(module);
-                    }
-                }
-            }
-            return res;
-        } catch (Throwable e) {
-            throw new GraalError(e);
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,14 +22,14 @@
  */
 package org.graalvm.compiler.hotspot.meta;
 
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
 import org.graalvm.compiler.hotspot.HotSpotBackend;
 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 @ClassSubstitution(className = {"jdk.internal.misc.Unsafe", "sun.misc.Unsafe"})
 public class HotSpotUnsafeSubstitutions {
@@ -41,7 +41,7 @@
     static void copyMemory(Object receiver, Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) {
         Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset));
         Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset));
-        Word size = Word.signed(bytes);
+        Word size = WordFactory.signed(bytes);
         HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import static org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode.POINTER_EQ;
 import static org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode.POINTER_NE;
 import static org.graalvm.compiler.nodes.ConstantNode.forBoolean;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BridgeMethodUtils;
@@ -53,7 +53,7 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.word.WordOperationPlugin;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.meta;
+
+import java.lang.module.ModuleDescriptor.Requires;
+
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+
+/**
+ * Determines if methods in a given class can be intrinsified.
+ *
+ * Only classes loaded from the module defining the compiler configuration or any of its transitive
+ * dependencies can be intrinsified.
+ *
+ * This version of the class must be used on JDK 9 or later.
+ */
+public final class IntrinsificationPredicate {
+    /**
+     * Set of modules composed of the module defining the compiler configuration and its transitive
+     * dependencies.
+     */
+    private final EconomicSet<Module> trustedModules;
+
+    IntrinsificationPredicate(CompilerConfiguration compilerConfiguration) {
+        trustedModules = EconomicSet.create();
+        Module compilerConfigurationModule = compilerConfiguration.getClass().getModule();
+        if (compilerConfigurationModule.getDescriptor().isAutomatic()) {
+            throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module",
+                            compilerConfigurationModule.getName(), compilerConfiguration.getClass().getName()));
+        }
+        trustedModules.add(compilerConfigurationModule);
+        for (Requires require : compilerConfigurationModule.getDescriptor().requires()) {
+            for (Module module : compilerConfigurationModule.getLayer().modules()) {
+                if (module.getName().equals(require.name())) {
+                    trustedModules.add(module);
+                }
+            }
+        }
+    }
+
+    public boolean apply(Class<?> declaringClass) {
+        Module module = declaringClass.getModule();
+        return trustedModules.contains(module);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/BeginLockScopeNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/BeginLockScopeNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,7 +38,7 @@
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/EndLockScopeNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/EndLockScopeNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Intrinsic for closing a {@linkplain BeginLockScopeNode scope} binding a stack-based lock with an
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/StubForeignCallNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/StubForeignCallNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,7 +42,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Value;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo(cycles = CYCLES_4, size = SIZE_16, allowedUsageTypes = {Memory})
 public class InitializeKlassNode extends DeoptimizingFixedWithNextNode implements Lowerable, MemoryCheckpoint.Single {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Tue Apr 24 09:04:57 2018 -0700
@@ -43,7 +43,7 @@
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.meta.Constant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16;
 
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.InputType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Tue Apr 24 09:04:57 2018 -0700
@@ -43,7 +43,7 @@
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.Value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,15 +25,12 @@
 import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
 
-import jdk.vm.ci.meta.DeoptimizationAction;
-import jdk.vm.ci.meta.DeoptimizationReason;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.CounterKey;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
@@ -74,6 +71,10 @@
 import org.graalvm.compiler.phases.Phase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.runtime.JVMCICompiler;
 
 public class OnStackReplacementPhase extends Phase {
@@ -97,6 +98,7 @@
     }
 
     @Override
+    @SuppressWarnings("try")
     protected void run(StructuredGraph graph) {
         DebugContext debug = graph.getDebug();
         if (graph.getEntryBCI() == JVMCICompiler.INVOCATION_ENTRY_BCI) {
@@ -158,64 +160,67 @@
             debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement loop peeling result");
         } while (true);
 
+        StartNode start = graph.start();
         FrameState osrState = osr.stateAfter();
-        osr.setStateAfter(null);
-        OSRStartNode osrStart = graph.add(new OSRStartNode());
-        StartNode start = graph.start();
-        FixedNode next = osr.next();
-        osr.setNext(null);
-        osrStart.setNext(next);
-        graph.setStart(osrStart);
-        osrStart.setStateAfter(osrState);
+        OSRStartNode osrStart;
+        try (DebugCloseable context = osr.withNodeSourcePosition()) {
+            osr.setStateAfter(null);
+            osrStart = graph.add(new OSRStartNode());
+            FixedNode next = osr.next();
+            osr.setNext(null);
+            osrStart.setNext(next);
+            graph.setStart(osrStart);
+            osrStart.setStateAfter(osrState);
+
+            debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement after setting OSR start");
+            final int localsSize = osrState.localsSize();
+            final int locksSize = osrState.locksSize();
 
-        debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement after setting OSR start");
-        final int localsSize = osrState.localsSize();
-        final int locksSize = osrState.locksSize();
+            for (int i = 0; i < localsSize + locksSize; i++) {
+                ValueNode value = null;
+                if (i >= localsSize) {
+                    value = osrState.lockAt(i - localsSize);
+                } else {
+                    value = osrState.localAt(i);
+                }
+                if (value instanceof EntryProxyNode) {
+                    EntryProxyNode proxy = (EntryProxyNode) value;
+                    /*
+                     * We need to drop the stamp since the types we see during OSR may be too
+                     * precise (if a branch was not parsed for example). In cases when this is
+                     * possible, we insert a guard and narrow the OSRLocal stamp at its usages.
+                     */
+                    Stamp narrowedStamp = proxy.value().stamp(NodeView.DEFAULT);
+                    Stamp unrestrictedStamp = proxy.stamp(NodeView.DEFAULT).unrestricted();
+                    ValueNode osrLocal;
+                    if (i >= localsSize) {
+                        osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
+                    } else {
+                        osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
+                    }
+                    // Speculate on the OSRLocal stamps that could be more precise.
+                    OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
+                    if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
+                        // Add guard.
+                        LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
+                        JavaConstant constant = graph.getSpeculationLog().speculate(reason);
+                        FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
+                        graph.addAfterFixed(osrStart, guard);
 
-        for (int i = 0; i < localsSize + locksSize; i++) {
-            ValueNode value = null;
-            if (i >= localsSize) {
-                value = osrState.lockAt(i - localsSize);
-            } else {
-                value = osrState.localAt(i);
+                        // Replace with a more specific type at usages.
+                        // We know that we are at the root,
+                        // so we need to replace the proxy in the state.
+                        proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
+                        osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
+                    }
+                    proxy.replaceAndDelete(osrLocal);
+                } else {
+                    assert value == null || value instanceof OSRLocalNode;
+                }
             }
-            if (value instanceof EntryProxyNode) {
-                EntryProxyNode proxy = (EntryProxyNode) value;
-                /*
-                 * We need to drop the stamp since the types we see during OSR may be too precise
-                 * (if a branch was not parsed for example). In cases when this is possible, we
-                 * insert a guard and narrow the OSRLocal stamp at its usages.
-                 */
-                Stamp narrowedStamp = proxy.value().stamp(NodeView.DEFAULT);
-                Stamp unrestrictedStamp = proxy.stamp(NodeView.DEFAULT).unrestricted();
-                ValueNode osrLocal;
-                if (i >= localsSize) {
-                    osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
-                } else {
-                    osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
-                }
-                // Speculate on the OSRLocal stamps that could be more precise.
-                OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
-                if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
-                    // Add guard.
-                    LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
-                    JavaConstant constant = graph.getSpeculationLog().speculate(reason);
-                    FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
-                    graph.addAfterFixed(osrStart, guard);
 
-                    // Replace with a more specific type at usages.
-                    // We know that we are at the root,
-                    // so we need to replace the proxy in the state.
-                    proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
-                    osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
-                }
-                proxy.replaceAndDelete(osrLocal);
-            } else {
-                assert value == null || value instanceof OSRLocalNode;
-            }
+            osr.replaceAtUsages(InputType.Guard, osrStart);
         }
-
-        osr.replaceAtUsages(InputType.Guard, osrStart);
         debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement after replacing entry proxies");
         GraphUtil.killCFG(start);
         debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement result");
@@ -223,21 +228,24 @@
 
         if (currentOSRWithLocks) {
             OsrWithLocksCount.increment(debug);
-            for (int i = osrState.monitorIdCount() - 1; i >= 0; --i) {
-                MonitorIdNode id = osrState.monitorIdAt(i);
-                ValueNode lockedObject = osrState.lockAt(i);
-                OSRMonitorEnterNode osrMonitorEnter = graph.add(new OSRMonitorEnterNode(lockedObject, id));
-                for (Node usage : id.usages()) {
-                    if (usage instanceof AccessMonitorNode) {
-                        AccessMonitorNode access = (AccessMonitorNode) usage;
-                        access.setObject(lockedObject);
+            try (DebugCloseable context = osrStart.withNodeSourcePosition()) {
+                for (int i = osrState.monitorIdCount() - 1; i >= 0; --i) {
+                    MonitorIdNode id = osrState.monitorIdAt(i);
+                    ValueNode lockedObject = osrState.lockAt(i);
+                    OSRMonitorEnterNode osrMonitorEnter = graph.add(new OSRMonitorEnterNode(lockedObject, id));
+                    for (Node usage : id.usages()) {
+                        if (usage instanceof AccessMonitorNode) {
+                            AccessMonitorNode access = (AccessMonitorNode) usage;
+                            access.setObject(lockedObject);
+                        }
                     }
+                    FixedNode oldNext = osrStart.next();
+                    oldNext.replaceAtPredecessor(null);
+                    osrMonitorEnter.setNext(oldNext);
+                    osrStart.setNext(osrMonitorEnter);
                 }
-                FixedNode oldNext = osrStart.next();
-                oldNext.replaceAtPredecessor(null);
-                osrMonitorEnter.setNext(oldNext);
-                osrStart.setNext(osrMonitorEnter);
             }
+
             debug.dump(DebugContext.DETAILED_LEVEL, graph, "After inserting OSR monitor enters");
             /*
              * Ensure balanced monitorenter - monitorexit
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot.phases;
 
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -53,22 +54,25 @@
         this.config = config;
     }
 
+    @SuppressWarnings("try")
     @Override
     protected void run(StructuredGraph graph) {
         for (Node n : graph.getNodes()) {
-            if (n instanceof ReadNode) {
-                addReadNodeBarriers((ReadNode) n, graph);
-            } else if (n instanceof WriteNode) {
-                addWriteNodeBarriers((WriteNode) n, graph);
-            } else if (n instanceof LoweredAtomicReadAndWriteNode) {
-                LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n;
-                addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph);
-            } else if (n instanceof AbstractCompareAndSwapNode) {
-                addCASBarriers((AbstractCompareAndSwapNode) n, graph);
-            } else if (n instanceof ArrayRangeWrite) {
-                ArrayRangeWrite node = (ArrayRangeWrite) n;
-                if (node.writesObjectArray()) {
-                    addArrayRangeBarriers(node, graph);
+            try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) {
+                if (n instanceof ReadNode) {
+                    addReadNodeBarriers((ReadNode) n, graph);
+                } else if (n instanceof WriteNode) {
+                    addWriteNodeBarriers((WriteNode) n, graph);
+                } else if (n instanceof LoweredAtomicReadAndWriteNode) {
+                    LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n;
+                    addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph);
+                } else if (n instanceof AbstractCompareAndSwapNode) {
+                    addCASBarriers((AbstractCompareAndSwapNode) n, graph);
+                } else if (n instanceof ArrayRangeWrite) {
+                    ArrayRangeWrite node = (ArrayRangeWrite) n;
+                    if (node.writesObjectArray()) {
+                        addArrayRangeBarriers(node, graph);
+                    }
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/AOTInliningPolicy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/AOTInliningPolicy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,6 +27,7 @@
 
 import java.util.Map;
 
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.spi.Replacements;
 import org.graalvm.compiler.options.Option;
@@ -36,6 +37,7 @@
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
 import org.graalvm.compiler.phases.common.inlining.info.InlineInfo;
 import org.graalvm.compiler.phases.common.inlining.policy.GreedyInliningPolicy;
+import org.graalvm.compiler.phases.common.inlining.policy.InliningPolicy;
 import org.graalvm.compiler.phases.common.inlining.walker.MethodInvocation;
 
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -61,13 +63,14 @@
     }
 
     @Override
-    public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+    public Decision isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+        final boolean isTracing = GraalOptions.TraceInlining.getValue(replacements.getOptions());
         final InlineInfo info = invocation.callee();
 
         for (int i = 0; i < info.numberOfMethods(); ++i) {
             HotSpotResolvedObjectType t = (HotSpotResolvedObjectType) info.methodAt(i).getDeclaringClass();
             if (t.getFingerprint() == 0) {
-                return false;
+                return InliningPolicy.Decision.NO;
             }
         }
 
@@ -77,17 +80,17 @@
         OptionValues options = info.graph().getOptions();
         if (InlineEverything.getValue(options)) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "inline everything");
         }
 
         if (isIntrinsic(replacements, info)) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "intrinsic");
         }
 
         if (info.shouldInline()) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "forced inlining");
         }
 
         double inliningBonus = getInliningBonus(info);
@@ -95,17 +98,18 @@
 
         if (nodes < TrivialInliningSize.getValue(options) * inliningBonus) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
         }
 
         double maximumNodes = computeMaximumSize(relevance, (int) (maxInliningSize(inliningDepth, options) * inliningBonus));
         if (nodes <= maximumNodes) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
                             nodes, maximumNodes);
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
+                            nodes, maximumNodes);
         }
 
         InliningUtil.traceNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
-        return false;
+        return InliningPolicy.Decision.NO.withReason(isTracing, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,7 +32,7 @@
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import java.util.HashSet;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -41,9 +41,9 @@
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32CSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32CSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,8 +32,8 @@
 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32Substitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32Substitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,9 +38,9 @@
 import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -40,9 +40,9 @@
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -48,7 +48,7 @@
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HashCodeSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HashCodeSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -47,7 +47,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.TargetDescription;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -59,8 +59,8 @@
 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
 import org.graalvm.compiler.replacements.nodes.WriteRegisterNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.Register;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -40,7 +40,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.meta.JavaConstant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/LoadExceptionObjectSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/LoadExceptionObjectSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -51,7 +51,7 @@
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.code.Register;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -120,10 +120,10 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.code.Register;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -117,8 +117,8 @@
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.MemoryBarriers;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,6 +24,11 @@
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
+import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
+import org.graalvm.compiler.graph.Node.NodeIntrinsic;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 
 // JaCoCo Exclude
 
@@ -37,4 +42,21 @@
     public static int hashCode(final Object thisObj) {
         return IdentityHashCodeNode.identityHashCode(thisObj);
     }
+
+    @MethodSubstitution(isStatic = false)
+    public static void notify(final Object thisObj) {
+        if (!fastNotifyStub(HotSpotHostForeignCallsProvider.NOTIFY, thisObj)) {
+            notify(thisObj);
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void notifyAll(final Object thisObj) {
+        if (!fastNotifyStub(HotSpotHostForeignCallsProvider.NOTIFY_ALL, thisObj)) {
+            notifyAll(thisObj);
+        }
+    }
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    public static native boolean fastNotifyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object o);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,7 +23,7 @@
 package org.graalvm.compiler.hotspot.replacements;
 
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
@@ -33,8 +33,8 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,7 +23,7 @@
 package org.graalvm.compiler.hotspot.replacements;
 
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
@@ -33,8 +33,8 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,7 +23,7 @@
 package org.graalvm.compiler.hotspot.replacements;
 
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
@@ -33,8 +33,8 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/StringToBytesSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/StringToBytesSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,7 +42,7 @@
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.replacements.nodes.CStringConstant;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ThreadSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ThreadSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.osThreadInterruptedOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.osThreadOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.threadObjectOffset;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -87,10 +87,10 @@
 import org.graalvm.compiler.replacements.Snippets;
 import org.graalvm.compiler.replacements.nodes.DirectStoreNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.TargetDescription;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -58,7 +58,7 @@
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.JavaConstant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.hotspot.replacements.arraycopy;
 
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -31,7 +31,7 @@
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Tue Apr 24 09:04:57 2018 -0700
@@ -40,7 +40,7 @@
 import java.lang.reflect.Method;
 import java.util.EnumMap;
 
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.api.replacements.Fold;
 import org.graalvm.compiler.api.replacements.Snippet;
@@ -77,8 +77,8 @@
 import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.DeoptimizationAction;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -52,7 +52,7 @@
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -42,7 +42,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,7 @@
 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.REEXECUTABLE;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.clearPendingException;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.api.replacements.Fold;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ExceptionHandlerStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ExceptionHandlerStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -51,7 +51,7 @@
 import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.Register;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,11 +34,9 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
-import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.JavaMethodContext;
-import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl;
@@ -57,7 +55,7 @@
 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
 import jdk.vm.ci.hotspot.HotSpotSignature;
@@ -232,33 +230,30 @@
         WordTypes wordTypes = providers.getWordTypes();
         Class<?>[] args = linkage.getDescriptor().getArgumentTypes();
         boolean isObjectResult = !LIRKind.isValue(linkage.getOutgoingCallingConvention().getReturn());
-        StructuredGraph graph = new StructuredGraph.Builder(options, debug).name(toString()).compilationId(compilationId).build();
-        graph.disableUnsafeAccessTracking();
-        graph.setTrackNodeSourcePosition();
+
         try {
             ResolvedJavaMethod thisMethod = providers.getMetaAccess().lookupJavaMethod(ForeignCallStub.class.getDeclaredMethod("getGraph", DebugContext.class, CompilationIdentifier.class));
-            try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(thisMethod))) {
-                GraphKit kit = new GraphKit(graph, providers, wordTypes, providers.getGraphBuilderPlugins());
-                ParameterNode[] params = createParameters(kit, args);
-                ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));
-                ValueNode result = createTargetCall(kit, params, thread);
-                kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, graph));
-                if (isObjectResult) {
-                    InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread);
-                    result = kit.createInvoke(StubUtil.class, "verifyObject", object);
-                }
-                kit.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result));
-                debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph");
+            GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString());
+            StructuredGraph graph = kit.getGraph();
+            ParameterNode[] params = createParameters(kit, args);
+            ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));
+            ValueNode result = createTargetCall(kit, params, thread);
+            kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, graph));
+            if (isObjectResult) {
+                InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread);
+                result = kit.createInvoke(StubUtil.class, "verifyObject", object);
+            }
+            kit.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result));
+            debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph");
 
-                kit.inlineInvokes();
-                new RemoveValueProxyPhase().apply(graph);
+            kit.inlineInvokes("Foreign call stub.", "Backend");
+            new RemoveValueProxyPhase().apply(graph);
 
-                debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Stub graph before compilation");
-            }
+            debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Stub graph before compilation");
+            return graph;
         } catch (Exception e) {
             throw GraalError.shouldNotReachHere(e);
         }
-        return graph;
     }
 
     private ParameterNode[] createParameters(GraphKit kit, Class<?>[] args) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -59,7 +59,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -81,7 +81,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -48,9 +48,10 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.TriState;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.target.Backend;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Description;
@@ -137,7 +138,7 @@
      */
     public Stub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
         this.linkage = linkage;
-        this.options = options;
+        this.options = new OptionValues(options, GraalOptions.TraceInlining, GraalOptions.TraceInliningForStubsAndSnippets.getValue(options));
         this.providers = providers;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -50,8 +50,8 @@
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.replacements.Log;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.DeoptimizationAction;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/UnwindExceptionToCallerStub.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/UnwindExceptionToCallerStub.java	Tue Apr 24 09:04:57 2018 -0700
@@ -47,7 +47,7 @@
 import org.graalvm.compiler.nodes.UnwindNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.word.Pointer;
 
 import jdk.vm.ci.code.Register;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/KlassPointer.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/KlassPointer.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,8 +29,8 @@
 
 import org.graalvm.compiler.word.Word.Opcode;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
 
 /**
  * Marker type for a metaspace pointer to a type.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MetaspacePointer.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MetaspacePointer.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,11 +29,11 @@
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.Word.Opcode;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.SignedWord;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordBase;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.SignedWord;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordBase;
 
 /**
  * Marker type for a metaspace pointer.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MethodPointer.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/MethodPointer.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 import static org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode.POINTER_NE;
 import static org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode.TO_METHOD_POINTER;
 
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.word.Pointer;
 
 /**
  * Marker type for a metaspace pointer to a method.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,6 +38,7 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.FASTORE;
 import static org.graalvm.compiler.bytecode.Bytecodes.FRETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.GETFIELD;
+import static org.graalvm.compiler.bytecode.Bytecodes.GETSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO_W;
 import static org.graalvm.compiler.bytecode.Bytecodes.IALOAD;
@@ -71,6 +72,7 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH;
 import static org.graalvm.compiler.bytecode.Bytecodes.LRETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD;
+import static org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.RET;
 import static org.graalvm.compiler.bytecode.Bytecodes.RETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.SALOAD;
@@ -81,13 +83,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeLookupSwitch;
 import org.graalvm.compiler.bytecode.BytecodeStream;
@@ -142,20 +143,20 @@
 
     public static class BciBlock implements Cloneable {
 
-        protected int id;
-        public int startBci;
-        public int endBci;
-        public boolean isExceptionEntry;
-        public boolean isLoopHeader;
-        public int loopId;
-        public int loopEnd;
-        protected List<BciBlock> successors;
+        int id;
+        final int startBci;
+        int endBci;
+        private boolean isExceptionEntry;
+        private boolean isLoopHeader;
+        int loopId;
+        int loopEnd;
+        List<BciBlock> successors;
         private int predecessorCount;
 
         private boolean visited;
         private boolean active;
-        public long loops;
-        public JSRData jsrData;
+        long loops;
+        JSRData jsrData;
 
         public static class JSRData implements Cloneable {
             public EconomicMap<JsrScope, BciBlock> jsrAlternatives;
@@ -174,8 +175,21 @@
             }
         }
 
-        public BciBlock() {
-            this.successors = new ArrayList<>(4);
+        BciBlock(int startBci) {
+            this.startBci = startBci;
+            this.successors = new ArrayList<>();
+        }
+
+        public int getStartBci() {
+            return startBci;
+        }
+
+        public int getEndBci() {
+            return endBci;
+        }
+
+        public long getLoops() {
+            return loops;
         }
 
         public BciBlock exceptionDispatchBlock() {
@@ -216,14 +230,16 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder("B").append(getId());
-            sb.append('[').append(startBci).append("->").append(endBci);
-            if (isLoopHeader || isExceptionEntry) {
+            sb.append('[').append(startBci).append("..").append(endBci);
+            if (isLoopHeader || isExceptionEntry || this instanceof ExceptionDispatchBlock) {
                 sb.append(' ');
                 if (isLoopHeader) {
                     sb.append('L');
                 }
                 if (isExceptionEntry) {
                     sb.append('!');
+                } else if (this instanceof ExceptionDispatchBlock) {
+                    sb.append("<!>");
                 }
             }
             sb.append(']');
@@ -412,11 +428,40 @@
             }
             successors.clear();
         }
+
+        public boolean isExceptionDispatch() {
+            return false;
+        }
     }
 
     public static class ExceptionDispatchBlock extends BciBlock {
-        public ExceptionHandler handler;
-        public int deoptBci;
+        public final ExceptionHandler handler;
+        public final int deoptBci;
+
+        /**
+         * Constructor for a normal dispatcher.
+         */
+        ExceptionDispatchBlock(ExceptionHandler handler, int deoptBci) {
+            super(handler.getHandlerBCI());
+            this.endBci = startBci;
+            this.deoptBci = deoptBci;
+            this.handler = handler;
+        }
+
+        /**
+         * Constructor for the method unwind dispatcher.
+         */
+        ExceptionDispatchBlock(int deoptBci) {
+            super(deoptBci);
+            this.endBci = deoptBci;
+            this.deoptBci = deoptBci;
+            this.handler = null;
+        }
+
+        @Override
+        public boolean isExceptionDispatch() {
+            return true;
+        }
     }
 
     /**
@@ -480,7 +525,6 @@
     private boolean verify() {
         for (BciBlock block : blocks) {
             assert blocks[block.getId()] == block;
-
             for (int i = 0; i < block.getSuccessorCount(); i++) {
                 BciBlock sux = block.getSuccessor(i);
                 if (sux instanceof ExceptionDispatchBlock) {
@@ -623,6 +667,8 @@
                 case CALOAD:
                 case SALOAD:
                 case ARRAYLENGTH:
+                case PUTSTATIC:
+                case GETSTATIC:
                 case PUTFIELD:
                 case GETFIELD: {
                     ExceptionDispatchBlock handler = handleExceptions(blockMap, bci);
@@ -640,18 +686,16 @@
     private BciBlock makeBlock(BciBlock[] blockMap, int startBci) {
         BciBlock oldBlock = blockMap[startBci];
         if (oldBlock == null) {
-            BciBlock newBlock = new BciBlock();
+            BciBlock newBlock = new BciBlock(startBci);
             blocksNotYetAssignedId++;
-            newBlock.startBci = startBci;
             blockMap[startBci] = newBlock;
             return newBlock;
 
         } else if (oldBlock.startBci != startBci) {
             // Backward branch into the middle of an already processed block.
             // Add the correct fall-through successor.
-            BciBlock newBlock = new BciBlock();
+            BciBlock newBlock = new BciBlock(startBci);
             blocksNotYetAssignedId++;
-            newBlock.startBci = startBci;
             newBlock.endBci = oldBlock.endBci;
             for (BciBlock oldSuccessor : oldBlock.getSuccessors()) {
                 newBlock.addSuccessor(oldSuccessor);
@@ -747,6 +791,7 @@
 
     private ExceptionDispatchBlock handleExceptions(BciBlock[] blockMap, int bci) {
         ExceptionDispatchBlock lastHandler = null;
+        int dispatchBlocks = 0;
 
         for (int i = exceptionHandlers.length - 1; i >= 0; i--) {
             ExceptionHandler h = exceptionHandlers[i];
@@ -754,17 +799,14 @@
                 if (h.isCatchAll()) {
                     // Discard all information about succeeding exception handlers, since they can
                     // never be reached.
+                    dispatchBlocks = 0;
                     lastHandler = null;
                 }
 
                 // We do not reuse exception dispatch blocks, because nested exception handlers
                 // might have problems reasoning about the correct frame state.
-                ExceptionDispatchBlock curHandler = new ExceptionDispatchBlock();
-                blocksNotYetAssignedId++;
-                curHandler.startBci = -1;
-                curHandler.endBci = -1;
-                curHandler.deoptBci = bci;
-                curHandler.handler = h;
+                ExceptionDispatchBlock curHandler = new ExceptionDispatchBlock(h, bci);
+                dispatchBlocks++;
                 curHandler.addSuccessor(blockMap[h.getHandlerBCI()]);
                 if (lastHandler != null) {
                     curHandler.addSuccessor(lastHandler);
@@ -772,6 +814,7 @@
                 lastHandler = curHandler;
             }
         }
+        blocksNotYetAssignedId += dispatchBlocks;
         return lastHandler;
     }
 
@@ -827,10 +870,8 @@
         assert next == newBlocks.length - 1;
 
         // Add unwind block.
-        ExceptionDispatchBlock unwindBlock = new ExceptionDispatchBlock();
-        unwindBlock.startBci = -1;
-        unwindBlock.endBci = -1;
-        unwindBlock.deoptBci = code.getMethod().isSynchronized() ? BytecodeFrame.UNWIND_BCI : BytecodeFrame.AFTER_EXCEPTION_BCI;
+        int deoptBci = code.getMethod().isSynchronized() ? BytecodeFrame.UNWIND_BCI : BytecodeFrame.AFTER_EXCEPTION_BCI;
+        ExceptionDispatchBlock unwindBlock = new ExceptionDispatchBlock(deoptBci);
         unwindBlock.setId(newBlocks.length - 1);
         newBlocks[newBlocks.length - 1] = unwindBlock;
 
@@ -858,42 +899,54 @@
 
     public void log(BciBlock[] blockMap, String name) {
         if (debug.isLogEnabled()) {
-            String n = System.lineSeparator();
-            StringBuilder sb = new StringBuilder(debug.getCurrentScopeName()).append("BlockMap ").append(name).append(" :");
-            sb.append(n);
-            Iterable<BciBlock> it;
-            if (blocks == null) {
-                it = new HashSet<>(Arrays.asList(blockMap));
-            } else {
-                it = Arrays.asList(blocks);
+            debug.log("%sBlockMap %s: %n%s", debug.getCurrentScopeName(), name, toString(blockMap, loopHeaders));
+        }
+    }
+
+    public static String toString(BciBlock[] blockMap, BciBlock[] loopHeadersMap) {
+        StringBuilder sb = new StringBuilder();
+        for (BciBlock b : blockMap) {
+            if (b == null) {
+                continue;
+            }
+            sb.append("B").append(b.getId()).append("[").append(b.startBci).append("..").append(b.endBci).append("]");
+            if (b.isLoopHeader) {
+                sb.append(" LoopHeader");
             }
-            for (BciBlock b : it) {
-                if (b == null) {
-                    continue;
-                }
-                sb.append("B").append(b.getId()).append(" (").append(b.startBci).append(" -> ").append(b.endBci).append(")");
-                if (b.isLoopHeader) {
-                    sb.append(" LoopHeader");
+            if (b.isExceptionEntry) {
+                sb.append(" ExceptionEntry");
+            }
+            if (b instanceof ExceptionDispatchBlock) {
+                sb.append(" ExceptionDispatch");
+            }
+            if (!b.successors.isEmpty()) {
+                sb.append(" Successors=[");
+                for (BciBlock s : b.getSuccessors()) {
+                    if (sb.charAt(sb.length() - 1) != '[') {
+                        sb.append(", ");
+                    }
+                    sb.append("B").append(s.getId());
                 }
-                if (b.isExceptionEntry) {
-                    sb.append(" ExceptionEntry");
-                }
-                sb.append(n).append("  Sux : ");
-                for (BciBlock s : b.getSuccessors()) {
-                    sb.append("B").append(s.getId()).append(" (").append(s.startBci).append(" -> ").append(s.endBci).append(")");
-                    if (s.isExceptionEntry) {
-                        sb.append("!");
+                sb.append("]");
+            }
+            if (b.loops != 0L) {
+                sb.append(" Loops=[");
+                for (int pos : b.loopIdIterable()) {
+                    if (sb.charAt(sb.length() - 1) == '[') {
+                        sb.append(", ");
                     }
-                    sb.append(" ");
+                    sb.append("B").append(loopHeadersMap[pos].getId());
                 }
-                sb.append(n).append("  Loop : ");
-                for (int pos : b.loopIdIterable()) {
-                    sb.append("B").append(loopHeaders[pos].getId()).append(" ");
-                }
-                sb.append(n);
+                sb.append("]");
             }
-            debug.log("%s", sb);
+            sb.append(System.lineSeparator());
         }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        return toString(blocks, loopHeaders);
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Tue Apr 24 09:04:57 2018 -0700
@@ -265,8 +265,8 @@
 import java.util.Formatter;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
@@ -297,8 +297,10 @@
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.Indent;
+import org.graalvm.compiler.debug.MethodFilter;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.graph.Graph.Mark;
 import org.graalvm.compiler.graph.Node;
@@ -325,6 +327,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.InliningLog;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
@@ -414,7 +417,7 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.util.ValueMergeUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.BytecodeFrame;
@@ -454,11 +457,17 @@
 
     /**
      * The minimum value to which {@link BytecodeParserOptions#TraceBytecodeParserLevel} must be set
-     * to trace the frame state before each bytecode instruction as it is parsed.
+     * to emit the frame state for each traced bytecode instruction.
      */
     public static final int TRACELEVEL_STATE = 2;
 
     /**
+     * The minimum value to which {@link BytecodeParserOptions#TraceBytecodeParserLevel} must be set
+     * to emit the block map for each traced method.
+     */
+    public static final int TRACELEVEL_BLOCKMAP = 3;
+
+    /**
      * Meters the number of actual bytecodes parsed.
      */
     public static final CounterKey BytecodesParsed = DebugContext.counter("BytecodesParsed");
@@ -681,6 +690,7 @@
     private ValueNode originalReceiver;
     private final boolean eagerInitializing;
     private final boolean uninitializedIsError;
+    private final int traceLevel;
 
     protected BytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method,
                     int entryBCI, IntrinsicContext intrinsicContext) {
@@ -714,12 +724,6 @@
 
         assert code.getCode() != null : "method must contain bytecodes: " + method;
 
-        if (TraceBytecodeParserLevel.getValue(options) != 0) {
-            if (!Assertions.assertionsEnabled()) {
-                throw new IllegalArgumentException("A non-zero " + TraceBytecodeParserLevel.getName() + " value requires assertions to be enabled");
-            }
-        }
-
         if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
             lnt = code.getLineNumberTable();
             previousLineNumber = -1;
@@ -729,6 +733,24 @@
         if (graphBuilderConfig.trackNodeSourcePosition() || (parent != null && parent.graph.trackNodeSourcePosition())) {
             graph.setTrackNodeSourcePosition();
         }
+
+        int level = TraceBytecodeParserLevel.getValue(options);
+        this.traceLevel = level != 0 ? refineTraceLevel(level) : 0;
+    }
+
+    private int refineTraceLevel(int level) {
+        ResolvedJavaMethod tmethod = graph.method();
+        if (tmethod == null) {
+            tmethod = method;
+        }
+        String filterValue = DebugOptions.MethodFilter.getValue(options);
+        if (filterValue != null) {
+            MethodFilter[] filters = MethodFilter.parse(filterValue);
+            if (!MethodFilter.matches(filters, tmethod)) {
+                return 0;
+            }
+        }
+        return level;
     }
 
     protected GraphBuilderPhase.Instance getGraphBuilderInstance() {
@@ -847,7 +869,7 @@
 
             currentBlock = blockMap.getStartBlock();
             setEntryState(startBlock, frameState);
-            if (startBlock.isLoopHeader) {
+            if (startBlock.isLoopHeader()) {
                 appendGoto(startBlock);
             } else {
                 setFirstInstruction(startBlock, lastInstr);
@@ -1676,6 +1698,7 @@
             targetMethod = originalMethod;
         }
         Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
+        graph.getInliningLog().addDecision(invoke, false, "GraphBuilderPhase", null, null, "bytecode parser did not replace invoke");
         if (partialIntrinsicExit) {
             // This invoke must never be later inlined as it might select the intrinsic graph.
             // Until there is a mechanism to guarantee that any late inlining will not select
@@ -2172,60 +2195,80 @@
     }
 
     private boolean inline(ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, BytecodeProvider intrinsicBytecodeProvider, ValueNode[] args) {
-        IntrinsicContext intrinsic = this.intrinsicContext;
-
-        if (intrinsic == null && !graphBuilderConfig.insertFullInfopoints() &&
-                        targetMethod.equals(inlinedMethod) &&
-                        (targetMethod.getModifiers() & (STATIC | SYNCHRONIZED)) == 0 &&
-                        tryFastInlineAccessor(args, targetMethod)) {
-            return true;
-        }
-
-        if (intrinsic != null && intrinsic.isCallToOriginal(targetMethod)) {
-            if (intrinsic.isCompilationRoot()) {
-                // A root compiled intrinsic needs to deoptimize
-                // if the slow path is taken. During frame state
-                // assignment, the deopt node will get its stateBefore
-                // from the start node of the intrinsic
-                append(new DeoptimizeNode(InvalidateRecompile, RuntimeConstraint));
-                printInlining(targetMethod, inlinedMethod, true, "compilation root (bytecode parsing)");
+        try (InliningLog.RootScope scope = graph.getInliningLog().openRootScope(targetMethod, bci())) {
+            IntrinsicContext intrinsic = this.intrinsicContext;
+
+            if (intrinsic == null && !graphBuilderConfig.insertFullInfopoints() &&
+                            targetMethod.equals(inlinedMethod) &&
+                            (targetMethod.getModifiers() & (STATIC | SYNCHRONIZED)) == 0 &&
+                            tryFastInlineAccessor(args, targetMethod)) {
                 return true;
-            } else {
-                if (intrinsic.getOriginalMethod().isNative()) {
-                    printInlining(targetMethod, inlinedMethod, false, "native method (bytecode parsing)");
-                    return false;
-                }
-                if (canInlinePartialIntrinsicExit() && InlinePartialIntrinsicExitDuringParsing.getValue(options)) {
-                    // Otherwise inline the original method. Any frame state created
-                    // during the inlining will exclude frame(s) in the
-                    // intrinsic method (see FrameStateBuilder.create(int bci)).
-                    notifyBeforeInline(inlinedMethod);
-                    printInlining(targetMethod, inlinedMethod, true, "partial intrinsic exit (bytecode parsing)");
-                    parseAndInlineCallee(intrinsic.getOriginalMethod(), args, null);
-                    notifyAfterInline(inlinedMethod);
+            }
+
+            if (intrinsic != null && intrinsic.isCallToOriginal(targetMethod)) {
+                if (intrinsic.isCompilationRoot()) {
+                    // A root compiled intrinsic needs to deoptimize
+                    // if the slow path is taken. During frame state
+                    // assignment, the deopt node will get its stateBefore
+                    // from the start node of the intrinsic
+                    append(new DeoptimizeNode(InvalidateRecompile, RuntimeConstraint));
+                    printInlining(targetMethod, inlinedMethod, true, "compilation root (bytecode parsing)");
+                    if (scope != null) {
+                        graph.getInliningLog().addDecision(scope.getInvoke(), true, "GraphBuilderPhase", null, null, "compilation root");
+                    }
                     return true;
                 } else {
-                    printInlining(targetMethod, inlinedMethod, false, "partial intrinsic exit (bytecode parsing)");
+                    if (intrinsic.getOriginalMethod().isNative()) {
+                        printInlining(targetMethod, inlinedMethod, false, "native method (bytecode parsing)");
+                        if (scope != null) {
+                            graph.getInliningLog().addDecision(scope.getInvoke(), false, "GraphBuilderPhase", null, null, "native method");
+                        }
+                        return false;
+                    }
+                    if (canInlinePartialIntrinsicExit() && InlinePartialIntrinsicExitDuringParsing.getValue(options)) {
+                        // Otherwise inline the original method. Any frame state created
+                        // during the inlining will exclude frame(s) in the
+                        // intrinsic method (see FrameStateBuilder.create(int bci)).
+                        notifyBeforeInline(inlinedMethod);
+                        printInlining(targetMethod, inlinedMethod, true, "partial intrinsic exit (bytecode parsing)");
+                        if (scope != null) {
+                            graph.getInliningLog().addDecision(scope.getInvoke(), true, "GraphBuilderPhase", null, null, "partial intrinsic exit");
+                        }
+                        parseAndInlineCallee(intrinsic.getOriginalMethod(), args, null);
+                        notifyAfterInline(inlinedMethod);
+                        return true;
+                    } else {
+                        printInlining(targetMethod, inlinedMethod, false, "partial intrinsic exit (bytecode parsing)");
+                        if (scope != null) {
+                            graph.getInliningLog().addDecision(scope.getInvoke(), false, "GraphBuilderPhase", null, null, "partial intrinsic exit");
+                        }
+                        return false;
+                    }
+                }
+            } else {
+                boolean isIntrinsic = intrinsicBytecodeProvider != null;
+                if (intrinsic == null && isIntrinsic) {
+                    assert !inlinedMethod.equals(targetMethod);
+                    intrinsic = new IntrinsicContext(targetMethod, inlinedMethod, intrinsicBytecodeProvider, INLINE_DURING_PARSING);
+                }
+                if (inlinedMethod.hasBytecodes()) {
+                    notifyBeforeInline(inlinedMethod);
+                    printInlining(targetMethod, inlinedMethod, true, "inline method (bytecode parsing)");
+                    if (scope != null) {
+                        graph.getInliningLog().addDecision(scope.getInvoke(), true, "GraphBuilderPhase", null, null, "inline method");
+                    }
+                    parseAndInlineCallee(inlinedMethod, args, intrinsic);
+                    notifyAfterInline(inlinedMethod);
+                } else {
+                    printInlining(targetMethod, inlinedMethod, false, "no bytecodes (abstract or native) (bytecode parsing)");
+                    if (scope != null) {
+                        graph.getInliningLog().addDecision(scope.getInvoke(), false, "GraphBuilderPhase", null, null, "no bytecodes (abstract or native)");
+                    }
                     return false;
                 }
             }
-        } else {
-            boolean isIntrinsic = intrinsicBytecodeProvider != null;
-            if (intrinsic == null && isIntrinsic) {
-                assert !inlinedMethod.equals(targetMethod);
-                intrinsic = new IntrinsicContext(targetMethod, inlinedMethod, intrinsicBytecodeProvider, INLINE_DURING_PARSING);
-            }
-            if (inlinedMethod.hasBytecodes()) {
-                notifyBeforeInline(inlinedMethod);
-                printInlining(targetMethod, inlinedMethod, true, "inline method (bytecode parsing)");
-                parseAndInlineCallee(inlinedMethod, args, intrinsic);
-                notifyAfterInline(inlinedMethod);
-            } else {
-                printInlining(targetMethod, inlinedMethod, false, "no bytecodes (abstract or native) (bytecode parsing)");
-                return false;
-            }
-        }
-        return true;
+            return true;
+        }
     }
 
     protected void notifyBeforeInline(ResolvedJavaMethod inlinedMethod) {
@@ -2700,7 +2743,7 @@
     @SuppressWarnings("try")
     private FixedNode createTarget(BciBlock block, FrameStateBuilder state, boolean canReuseInstruction, boolean canReuseState) {
         assert block != null && state != null;
-        assert !block.isExceptionEntry || state.stackSize() == 1;
+        assert !block.isExceptionEntry() || state.stackSize() == 1;
 
         try (DebugCloseable context = openNodeContext(state, block.startBci)) {
             if (getFirstInstruction(block) == null) {
@@ -2710,7 +2753,7 @@
                  * again.
                  */
                 FixedNode targetNode;
-                if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) {
+                if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader() && (currentBlock.loops & ~block.loops) == 0) {
                     setFirstInstruction(block, lastInstr);
                     lastInstr = null;
                 } else {
@@ -2729,11 +2772,11 @@
 
             // We already saw this block before, so we have to merge states.
             if (!getEntryState(block).isCompatibleWith(state)) {
-                throw bailout("stacks do not match; bytecodes would not verify");
+                throw bailout(String.format("stacks do not match on merge from %d into %s; bytecodes would not verify:%nexpect: %s%nactual: %s", bci(), block, getEntryState(block), state));
             }
 
             if (getFirstInstruction(block) instanceof LoopBeginNode) {
-                assert (block.isLoopHeader && currentBlock.getId() >= block.getId()) : "must be backward branch";
+                assert (block.isLoopHeader() && currentBlock.getId() >= block.getId()) : "must be backward branch";
                 /*
                  * Backward loop edge. We need to create a special LoopEndNode and merge with the
                  * loop begin node created before.
@@ -2820,7 +2863,7 @@
             debug.log("Ignoring block %s", block);
             return;
         }
-        try (Indent indent = debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, firstInstruction, block.isLoopHeader)) {
+        try (Indent indent = debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, firstInstruction, block.isLoopHeader())) {
 
             lastInstr = firstInstruction;
             frameState = getEntryState(block);
@@ -2949,11 +2992,11 @@
 
     @SuppressWarnings("try")
     protected void iterateBytecodesForBlock(BciBlock block) {
-        if (block.isLoopHeader) {
+        if (block.isLoopHeader()) {
             // Create the loop header block, which later will merge the backward branches of
             // the loop.
             controlFlowSplit = true;
-            LoopBeginNode loopBegin = appendLoopBegin(this.lastInstr);
+            LoopBeginNode loopBegin = appendLoopBegin(this.lastInstr, block.startBci);
             lastInstr = loopBegin;
 
             // Create phi functions for all local variables and operand stack slots.
@@ -3007,8 +3050,9 @@
 
                 // read the opcode
                 int opcode = stream.currentBC();
-                assert traceState();
-                assert traceInstruction(bci, opcode, bci == block.startBci);
+                if (traceLevel != 0) {
+                    traceInstruction(bci, opcode, bci == block.startBci);
+                }
                 if (parent == null && bci == entryBCI) {
                     if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) {
                         throw new JsrNotSupportedBailout("OSR into a JSR scope is not supported");
@@ -3038,7 +3082,7 @@
             lastInstr = finishInstruction(lastInstr, frameState);
             if (bci < endBCI) {
                 if (bci > block.endBci) {
-                    assert !block.getSuccessor(0).isExceptionEntry;
+                    assert !block.getSuccessor(0).isExceptionEntry();
                     assert block.numNormalSuccessors() == 1;
                     // we fell through to the next block, add a goto and break
                     appendGoto(block.getSuccessor(0));
@@ -3097,16 +3141,19 @@
         return parsingIntrinsic();
     }
 
-    private LoopBeginNode appendLoopBegin(FixedWithNextNode fixedWithNext) {
-        EndNode preLoopEnd = graph.add(new EndNode());
-        LoopBeginNode loopBegin = graph.add(new LoopBeginNode());
-        if (disableLoopSafepoint()) {
-            loopBegin.disableSafepoint();
-        }
-        fixedWithNext.setNext(preLoopEnd);
-        // Add the single non-loop predecessor of the loop header.
-        loopBegin.addForwardEnd(preLoopEnd);
-        return loopBegin;
+    @SuppressWarnings("try")
+    private LoopBeginNode appendLoopBegin(FixedWithNextNode fixedWithNext, int startBci) {
+        try (DebugCloseable context = openNodeContext(frameState, startBci)) {
+            EndNode preLoopEnd = graph.add(new EndNode());
+            LoopBeginNode loopBegin = graph.add(new LoopBeginNode());
+            if (disableLoopSafepoint()) {
+                loopBegin.disableSafepoint();
+            }
+            fixedWithNext.setNext(preLoopEnd);
+            // Add the single non-loop predecessor of the loop header.
+            loopBegin.addForwardEnd(preLoopEnd);
+            return loopBegin;
+        }
     }
 
     /**
@@ -3126,13 +3173,6 @@
         }
     }
 
-    private boolean traceState() {
-        if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
-            frameState.traceState();
-        }
-        return true;
-    }
-
     protected void genIf(ValueNode x, Condition cond, ValueNode y) {
         assert x.getStackKind() == y.getStackKind();
         assert currentBlock.getSuccessorCount() == 2;
@@ -3249,19 +3289,23 @@
             }
 
             if (isNeverExecutedCode(probability)) {
-                append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
-                if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
-                    profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
+                if (!graph.isOSR() || getParent() != null || graph.getEntryBCI() != trueBlock.startBci) {
+                    append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
+                    if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
+                        profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
+                    }
+                    appendGoto(falseBlock);
+                    return;
                 }
-                appendGoto(falseBlock);
-                return;
             } else if (isNeverExecutedCode(1 - probability)) {
-                append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false));
-                if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
-                    profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
+                if (!graph.isOSR() || getParent() != null || graph.getEntryBCI() != falseBlock.startBci) {
+                    append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false));
+                    if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
+                        profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
+                    }
+                    appendGoto(trueBlock);
+                    return;
                 }
-                appendGoto(trueBlock);
-                return;
             }
 
             if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
@@ -4677,15 +4721,25 @@
         return frameState;
     }
 
-    protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
-        if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
-            traceInstructionHelper(bci, opcode, blockStart);
-        }
-        return true;
-    }
-
-    private void traceInstructionHelper(int bci, int opcode, boolean blockStart) {
+    private boolean firstTraceEmitted;
+
+    protected void traceInstruction(int bci, int opcode, boolean blockStart) {
+        String indent = new String(new char[getDepth() * 2]).replace('\0', ' ');
         StringBuilder sb = new StringBuilder(40);
+        String nl = System.lineSeparator();
+        if (!firstTraceEmitted) {
+            sb.append(indent).append(method.format("Parsing %H.%n(%p)%r")).append(nl);
+            if (traceLevel >= TRACELEVEL_BLOCKMAP) {
+                sb.append(indent).append("Blocks:").append(nl);
+                String bm = blockMap.toString().replace(nl, nl + indent + "  ");
+                sb.append(indent).append("  ").append(bm).append(nl);
+            }
+            firstTraceEmitted = true;
+        }
+        if (traceLevel >= TRACELEVEL_STATE) {
+            sb.append(indent).append(frameState).append(nl);
+        }
+        sb.append(indent);
         sb.append(blockStart ? '+' : '|');
         if (bci < 10) {
             sb.append("  ");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,8 +35,10 @@
 public class BytecodeParserOptions {
     // @formatter:off
     @Option(help = "The trace level for the bytecode parser. A value of 1 enables instruction tracing " +
-                   "and any greater value emits a frame state trace just prior to an instruction trace. " +
-                   "This option requires assertions to be enabled.", type = OptionType.Debug)
+                   "and any greater value emits a frame state trace just prior to each instruction trace." +
+                   "Instruction tracing output from multiple compiler threads will be interleaved so " +
+                   "use of this option make most sense for single threaded compilation. " +
+                   "The MethodFilter option can be used to refine tracing to selected methods.", type = OptionType.Debug)
     public static final OptionKey<Integer> TraceBytecodeParserLevel = new OptionKey<>(0);
 
     @Option(help = "Inlines trivial methods during bytecode parsing.", type = OptionType.Expert)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/ComputeLoopFrequenciesClosure.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/ComputeLoopFrequenciesClosure.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.ControlSplitNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -46,7 +46,6 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
 import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
 import org.graalvm.compiler.nodeinfo.Verbosity;
@@ -982,16 +981,4 @@
         }
         sideEffects.add(sideEffect);
     }
-
-    public void traceState() {
-        TTY.println("|   state [nr locals = %d, stack depth = %d, method = %s]", localsSize(), stackSize(), getMethod());
-        for (int i = 0; i < localsSize(); ++i) {
-            ValueNode value = locals[i];
-            TTY.println("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
-        }
-        for (int i = 0; i < stackSize(); ++i) {
-            ValueNode value = stack[i];
-            TTY.println("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/LocalLiveness.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/LocalLiveness.java	Tue Apr 24 09:04:57 2018 -0700
@@ -220,7 +220,7 @@
     protected abstract void storeOne(int blockID, int local);
 
     private void computeLocalLiveness(BytecodeStream stream, BciBlock block) {
-        if (block.startBci < 0 || block.endBci < 0) {
+        if (block.isExceptionDispatch()) {
             return;
         }
         int blockID = block.getId();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayCompareToOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.lir.aarch64;
+
+import static jdk.vm.ci.aarch64.AArch64.zr;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+
+import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.aarch64.AArch64Address;
+import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
+import sun.misc.Unsafe;
+
+/**
+ * Emits code which compares two arrays lexicographically. If the CPU supports any vector
+ * instructions specialized code is emitted to leverage these instructions.
+ */
+@Opcode("ARRAY_COMPARE_TO")
+public final class AArch64ArrayCompareToOp extends AArch64LIRInstruction {
+    public static final LIRInstructionClass<AArch64ArrayCompareToOp> TYPE = LIRInstructionClass.create(AArch64ArrayCompareToOp.class);
+
+    private final JavaKind kind1;
+    private final JavaKind kind2;
+
+    private final int array1BaseOffset;
+    private final int array2BaseOffset;
+
+    @Def({REG}) protected Value resultValue;
+
+    @Alive({REG}) protected Value array1Value;
+    @Alive({REG}) protected Value array2Value;
+    @Use({REG}) protected Value length1Value;
+    @Use({REG}) protected Value length2Value;
+    @Temp({REG}) protected Value length1ValueTemp;
+    @Temp({REG}) protected Value length2ValueTemp;
+
+    @Temp({REG}) protected Value temp1;
+    @Temp({REG}) protected Value temp2;
+    @Temp({REG}) protected Value temp3;
+    @Temp({REG}) protected Value temp4;
+    @Temp({REG}) protected Value temp5;
+    @Temp({REG}) protected Value temp6;
+
+    public AArch64ArrayCompareToOp(LIRGeneratorTool tool, JavaKind kind1, JavaKind kind2, Value result, Value array1, Value array2, Value length1, Value length2) {
+        super(TYPE);
+        this.kind1 = kind1;
+        this.kind2 = kind2;
+
+        // Both offsets should be the same but better be safe than sorry.
+        Class<?> array1Class = Array.newInstance(kind1.toJavaClass(), 0).getClass();
+        Class<?> array2Class = Array.newInstance(kind2.toJavaClass(), 0).getClass();
+        this.array1BaseOffset = UNSAFE.arrayBaseOffset(array1Class);
+        this.array2BaseOffset = UNSAFE.arrayBaseOffset(array2Class);
+
+        this.resultValue = result;
+
+        this.array1Value = array1;
+        this.array2Value = array2;
+
+        /*
+         * The length values are inputs but are also killed like temporaries so need both Use and
+         * Temp annotations, which will only work with fixed registers.
+         */
+
+        this.length1Value = length1;
+        this.length2Value = length2;
+        this.length1ValueTemp = length1;
+        this.length2ValueTemp = length2;
+
+        // Allocate some temporaries.
+        this.temp1 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        this.temp2 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        this.temp3 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        this.temp4 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        this.temp5 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        this.temp6 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+    }
+
+    private static final Unsafe UNSAFE = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            try {
+                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafe.setAccessible(true);
+                return (Unsafe) theUnsafe.get(Unsafe.class);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to get Unsafe", e);
+            }
+        }
+    }
+
+    @Override
+    protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+
+        Register result = asRegister(resultValue);
+        Register length1 = asRegister(length1Value);
+        Register length2 = asRegister(length2Value);
+
+        Register array1 = asRegister(temp1);
+        Register array2 = asRegister(temp2);
+        Register length = asRegister(temp3);
+        Register temp = asRegister(temp4);
+        Register tailCount = asRegister(temp5);
+        Register vecCount = asRegister(temp6);
+
+        // Checkstyle: stop
+        final Label BREAK_LABEL = new Label();
+        final Label STRING_DIFFER_LABEL = new Label();
+        final Label LENGTH_DIFFER_LABEL = new Label();
+        final Label MAIN_LOOP_LABEL = new Label();
+        final Label COMPARE_SHORT_LABEL = new Label();
+        // Checkstyle: resume
+
+        // Checkstyle: stop
+        int CHAR_SIZE_BYTES = 1;
+        int VECTOR_SIZE_BYTES = 8;
+        int VECTOR_COUNT_BYTES = 8;
+        // Checkstyle: resume
+
+        // Byte is expanded to short if we compare strings with different encoding
+        if (kind1 != kind2 || kind1 == JavaKind.Char) {
+            CHAR_SIZE_BYTES = 2;
+        }
+
+        if (kind1 != kind2) {
+            VECTOR_COUNT_BYTES = 4;
+        }
+
+        // Load array base addresses.
+        masm.lea(array1, AArch64Address.createUnscaledImmediateAddress(asRegister(array1Value), array1BaseOffset));
+        masm.lea(array2, AArch64Address.createUnscaledImmediateAddress(asRegister(array2Value), array2BaseOffset));
+
+        // Calculate minimal length in chars for different kind case
+        // Conditions could be squashed but lets keep it readable
+        if (kind1 != kind2) {
+            masm.lshr(64, length2, length2, 1);
+        }
+
+        if (kind1 == kind2 && kind1 == JavaKind.Char) {
+            masm.lshr(64, length1, length1, 1);
+            masm.lshr(64, length2, length2, 1);
+        }
+
+        masm.cmp(64, length1, length2);
+        masm.cmov(64, length, length1, length2, ConditionFlag.LT);
+
+        // One of strings is empty
+        masm.cbz(64, length, LENGTH_DIFFER_LABEL);
+
+        // Go back to bytes if necessary
+        if (kind1 != kind2 || kind1 == JavaKind.Char) {
+            masm.shl(64, length, length, 1);
+        }
+
+        masm.mov(64, vecCount, zr);
+        masm.and(64, tailCount, length, VECTOR_SIZE_BYTES - 1); // tail count (in bytes)
+        masm.ands(64, length, length, ~(VECTOR_SIZE_BYTES - 1));  // vector count (in bytes)
+
+        // Length of string is less than VECTOR_SIZE, go to simple compare
+        masm.branchConditionally(ConditionFlag.EQ, COMPARE_SHORT_LABEL);
+
+        // MAIN_LOOP - read strings by 8 byte.
+        masm.bind(MAIN_LOOP_LABEL);
+        if (kind1 != kind2) {
+            // Load 32 bits ad unpack it to entire 64bit register
+            masm.ldr(32, result, AArch64Address.createRegisterOffsetAddress(array1, vecCount, false));
+            masm.ubfm(64, temp, result, 0, 7);
+            masm.lshr(64, result, result, 8);
+            masm.bfm(64, temp, result, 48, 7);
+            masm.lshr(64, result, result, 8);
+            masm.bfm(64, temp, result, 32, 7);
+            masm.lshr(64, result, result, 8);
+            masm.bfm(64, temp, result, 16, 7);
+            // Unpacked value placed in temp now
+
+            masm.shl(64, result, vecCount, 1);
+            masm.ldr(64, result, AArch64Address.createRegisterOffsetAddress(array2, result, false));
+        } else {
+            masm.ldr(64, temp, AArch64Address.createRegisterOffsetAddress(array1, vecCount, false));
+            masm.ldr(64, result, AArch64Address.createRegisterOffsetAddress(array2, vecCount, false));
+        }
+        masm.eor(64, result, temp, result);
+        masm.cbnz(64, result, STRING_DIFFER_LABEL);
+        masm.add(64, vecCount, vecCount, VECTOR_COUNT_BYTES);
+        masm.cmp(64, vecCount, length);
+        masm.branchConditionally(ConditionFlag.LT, MAIN_LOOP_LABEL);
+        // End of MAIN_LOOP
+
+        // Strings are equal and no TAIL go to END
+        masm.cbz(64, tailCount, LENGTH_DIFFER_LABEL);
+
+        // Compaire tail of long string ...
+        masm.lea(array1, AArch64Address.createRegisterOffsetAddress(array1, length, false));
+        masm.lea(array2, AArch64Address.createRegisterOffsetAddress(array2, length, false));
+
+        // ... or string less than vector length
+        masm.bind(COMPARE_SHORT_LABEL);
+        for (int i = 0; i < VECTOR_COUNT_BYTES; i += CHAR_SIZE_BYTES) {
+            if (kind1 != kind2) {
+                masm.ldr(8, temp, AArch64Address.createUnscaledImmediateAddress(array1, i / 2));
+            } else {
+                masm.ldr(8 * CHAR_SIZE_BYTES, temp, AArch64Address.createUnscaledImmediateAddress(array1, i));
+            }
+
+            masm.ldr(8 * CHAR_SIZE_BYTES, result, AArch64Address.createUnscaledImmediateAddress(array2, i));
+
+            if (kind1 != kind2 && kind1 == JavaKind.Char) {
+                // Weird swap of substraction order
+                masm.subs(64, result, result, temp);
+            } else {
+                masm.subs(64, result, temp, result);
+            }
+
+            masm.branchConditionally(ConditionFlag.NE, BREAK_LABEL);
+            masm.subs(64, tailCount, tailCount, CHAR_SIZE_BYTES);
+            masm.branchConditionally(ConditionFlag.EQ, LENGTH_DIFFER_LABEL);
+        }
+
+        // STRING_DIFFER extract exact value of a difference
+        masm.bind(STRING_DIFFER_LABEL);
+        masm.rbit(64, tailCount, result);
+        masm.clz(64, vecCount, tailCount);
+        masm.and(64, vecCount, vecCount, ~((8 * CHAR_SIZE_BYTES) - 1)); // Round to byte or short
+
+        masm.eor(64, result, temp, result);
+        masm.ashr(64, result, result, vecCount);
+        masm.ashr(64, temp, temp, vecCount);
+
+        masm.and(64, result, result, 0xFFFF >>> (16 - (8 * CHAR_SIZE_BYTES))); // 0xFF or 0xFFFF
+        masm.and(64, temp, temp, 0xFFFF >>> (16 - (8 * CHAR_SIZE_BYTES)));
+
+        masm.sub(64, result, temp, result);
+        masm.branchConditionally(ConditionFlag.AL, BREAK_LABEL);
+        // End of STRING_DIFFER
+
+        // Strings are equials up to length,
+        // return length difference in chars
+        masm.bind(LENGTH_DIFFER_LABEL);
+        if (kind1 != kind2 && kind1 == JavaKind.Char) {
+            // Weird swap of substraction order
+            masm.sub(64, result, length2, length1);
+        } else {
+            masm.sub(64, result, length1, length2);
+        }
+
+        // We are done
+        masm.bind(BREAK_LABEL);
+    }
+
+} // class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64AtomicMove.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.lir.aarch64;
+
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+
+import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
+import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+
+import jdk.vm.ci.aarch64.AArch64.CPUFeature;
+import jdk.vm.ci.aarch64.AArch64.Flag;
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
+
+public class AArch64AtomicMove {
+    /**
+     * Compare and swap instruction. Does the following atomically: <code>
+     *  CAS(newVal, expected, address):
+     *    oldVal = *address
+     *    if oldVal == expected:
+     *        *address = newVal
+     *    return oldVal
+     * </code>
+     */
+    @Opcode("CAS")
+    public static class CompareAndSwapOp extends AArch64LIRInstruction {
+        public static final LIRInstructionClass<CompareAndSwapOp> TYPE = LIRInstructionClass.create(CompareAndSwapOp.class);
+
+        @Def protected AllocatableValue resultValue;
+        @Alive protected Value expectedValue;
+        @Alive protected AllocatableValue newValue;
+        @Alive protected AllocatableValue addressValue;
+        @Temp protected AllocatableValue scratchValue;
+
+        public CompareAndSwapOp(AllocatableValue result, Value expectedValue, AllocatableValue newValue, AllocatableValue addressValue, AllocatableValue scratch) {
+            super(TYPE);
+            this.resultValue = result;
+            this.expectedValue = expectedValue;
+            this.newValue = newValue;
+            this.addressValue = addressValue;
+            this.scratchValue = scratch;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+            AArch64Kind kind = (AArch64Kind) expectedValue.getPlatformKind();
+            assert kind.isInteger();
+            final int size = kind.getSizeInBytes() * Byte.SIZE;
+
+            Register address = asRegister(addressValue);
+            Register result = asRegister(resultValue);
+            Register newVal = asRegister(newValue);
+             if (masm.supports(CPUFeature.LSE) || masm.isFlagSet(Flag.UseLSE)) {
+                Register expected = asRegister(expectedValue);
+                masm.mov(size, result, expected);
+                masm.cas(size, expected, newVal, address, true /*acquire*/, true /*release*/);
+                AArch64Compare.gpCompare(masm, resultValue, expectedValue);
+            } else {
+                // We could avoid using a scratch register here, by reusing resultValue for the stlxr
+                // success flag and issue a mov resultValue, expectedValue in case of success before
+                // returning.
+                Register scratch = asRegister(scratchValue);
+                Label retry = new Label();
+                Label fail = new Label();
+                masm.bind(retry);
+                masm.ldaxr(size, result, address);
+                AArch64Compare.gpCompare(masm, resultValue, expectedValue);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.NE, fail);
+                masm.stlxr(size, scratch, newVal, address);
+                // if scratch == 0 then write successful, else retry.
+                masm.cbnz(32, scratch, retry);
+                masm.bind(fail);
+            }
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,9 +37,7 @@
 import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
 
-import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
-import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister;
 import org.graalvm.compiler.core.common.LIRKind;
@@ -339,60 +337,6 @@
         }
     }
 
-    /**
-     * Compare and swap instruction. Does the following atomically: <code>
-     *  CAS(newVal, expected, address):
-     *    oldVal = *address
-     *    if oldVal == expected:
-     *        *address = newVal
-     *    return oldVal
-     * </code>
-     */
-    @Opcode("CAS")
-    public static class CompareAndSwapOp extends AArch64LIRInstruction {
-        public static final LIRInstructionClass<CompareAndSwapOp> TYPE = LIRInstructionClass.create(CompareAndSwapOp.class);
-
-        @Def protected AllocatableValue resultValue;
-        @Alive protected Value expectedValue;
-        @Alive protected AllocatableValue newValue;
-        @Alive protected AllocatableValue addressValue;
-        @Temp protected AllocatableValue scratchValue;
-
-        public CompareAndSwapOp(AllocatableValue result, Value expectedValue, AllocatableValue newValue, AllocatableValue addressValue, AllocatableValue scratch) {
-            super(TYPE);
-            this.resultValue = result;
-            this.expectedValue = expectedValue;
-            this.newValue = newValue;
-            this.addressValue = addressValue;
-            this.scratchValue = scratch;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
-            AArch64Kind kind = (AArch64Kind) expectedValue.getPlatformKind();
-            assert kind.isInteger();
-            final int size = kind.getSizeInBytes() * Byte.SIZE;
-
-            Register address = asRegister(addressValue);
-            Register result = asRegister(resultValue);
-            Register newVal = asRegister(newValue);
-            Register scratch = asRegister(scratchValue);
-            // We could avoid using a scratch register here, by reusing resultValue for the stlxr
-            // success flag and issue a mov resultValue, expectedValue in case of success before
-            // returning.
-            Label retry = new Label();
-            Label fail = new Label();
-            masm.bind(retry);
-            masm.ldaxr(size, result, address);
-            AArch64Compare.gpCompare(masm, resultValue, expectedValue);
-            masm.branchConditionally(AArch64Assembler.ConditionFlag.NE, fail);
-            masm.stlxr(size, scratch, newVal, address);
-            // if scratch == 0 then write successful, else retry.
-            masm.cbnz(32, scratch, retry);
-            masm.bind(fail);
-        }
-    }
-
     private static void emitStore(@SuppressWarnings("unused") CompilationResultBuilder crb, AArch64MacroAssembler masm, AArch64Kind kind, AArch64Address dst, Value src) {
         int destSize = kind.getSizeInBytes() * Byte.SIZE;
         if (kind.isInteger()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -71,8 +71,10 @@
     @Def({REG}) protected Value resultValue;
     @Alive({REG}) protected Value array1Value;
     @Alive({REG}) protected Value array2Value;
-    @Alive({REG}) protected Value length1Value;
-    @Alive({REG}) protected Value length2Value;
+    @Use({REG}) protected Value length1Value;
+    @Use({REG}) protected Value length2Value;
+    @Temp({REG}) protected Value length1ValueTemp;
+    @Temp({REG}) protected Value length2ValueTemp;
     @Temp({REG}) protected Value temp1;
     @Temp({REG}) protected Value temp2;
 
@@ -92,8 +94,14 @@
         this.resultValue = result;
         this.array1Value = array1;
         this.array2Value = array2;
+        /*
+         * The length values are inputs but are also killed like temporaries so need both Use and
+         * Temp annotations, which will only work with fixed registers.
+         */
         this.length1Value = length1;
         this.length2Value = length2;
+        this.length1ValueTemp = length1;
+        this.length2ValueTemp = length2;
 
         // Allocate some temporaries.
         this.temp1 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SaveRegistersOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SaveRegistersOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,7 @@
 
 import java.util.Arrays;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.LIRValueUtil;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZapRegistersOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZapRegistersOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.lir.amd64.AMD64SaveRegistersOp.prune;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java	Tue Apr 24 09:04:57 2018 -0700
@@ -78,8 +78,8 @@
 import java.util.EnumSet;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Assembler.LabelHint;
 import org.graalvm.compiler.asm.Label;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCSaveRegistersOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCSaveRegistersOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 
 import java.util.Arrays;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.sparc.SPARCAddress;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.test/src/org/graalvm/compiler/lir/test/alloc/trace/TraceGlobalMoveResolutionMappingTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.test/src/org/graalvm/compiler/lir/test/alloc/trace/TraceGlobalMoveResolutionMappingTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,7 +27,7 @@
 
 import java.util.HashSet;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.lir.alloc.trace.ShadowedRegisterValue;
 import org.graalvm.compiler.lir.alloc.trace.TraceGlobalMoveResolutionPhase;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,9 +33,9 @@
 import java.util.Arrays;
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.core.common.FieldIntrospection;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.core.common.FieldsScanner;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,8 +30,8 @@
 import java.util.Collections;
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.CounterKey;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/StandardOp.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/StandardOp.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,7 +31,7 @@
 import java.util.ArrayList;
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.GraalError;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/RegisterAllocationPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.lir.alloc;
+
+import org.graalvm.compiler.lir.phases.AllocationPhase;
+
+/**
+ * Marker class for register allocation phases.
+ */
+public abstract class RegisterAllocationPhase extends AllocationPhase {
+    private boolean neverSpillConstants;
+
+    public void setNeverSpillConstants(boolean neverSpillConstants) {
+        this.neverSpillConstants = neverSpillConstants;
+    }
+
+    public boolean getNeverSpillConstants() {
+        return neverSpillConstants;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,7 +35,7 @@
 import java.util.BitSet;
 import java.util.EnumSet;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,8 +35,8 @@
 import java.util.BitSet;
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder;
@@ -160,12 +160,14 @@
         intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops());
 
         try {
+            final BitSet liveGenScratch = new BitSet(liveSize);
+            final BitSet liveKillScratch = new BitSet(liveSize);
             // iterate all blocks
             for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
                 try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
 
-                    final BitSet liveGen = new BitSet(liveSize);
-                    final BitSet liveKill = new BitSet(liveSize);
+                    liveGenScratch.clear();
+                    liveKillScratch.clear();
 
                     ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
                     int numInst = instructions.size();
@@ -173,8 +175,8 @@
                     ValueConsumer useConsumer = (operand, mode, flags) -> {
                         if (isVariable(operand)) {
                             int operandNum = allocator.operandNumber(operand);
-                            if (!liveKill.get(operandNum)) {
-                                liveGen.set(operandNum);
+                            if (!liveKillScratch.get(operandNum)) {
+                                liveGenScratch.set(operandNum);
                                 if (debug.isLogEnabled()) {
                                     debug.log("liveGen for operand %d(%s)", operandNum, operand);
                                 }
@@ -185,14 +187,14 @@
                         }
 
                         if (allocator.detailedAsserts) {
-                            verifyInput(block, liveKill, operand);
+                            verifyInput(block, liveKillScratch, operand);
                         }
                     };
                     ValueConsumer stateConsumer = (operand, mode, flags) -> {
                         if (LinearScan.isVariableOrRegister(operand)) {
                             int operandNum = allocator.operandNumber(operand);
-                            if (!liveKill.get(operandNum)) {
-                                liveGen.set(operandNum);
+                            if (!liveKillScratch.get(operandNum)) {
+                                liveGenScratch.set(operandNum);
                                 if (debug.isLogEnabled()) {
                                     debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
                                 }
@@ -202,7 +204,7 @@
                     ValueConsumer defConsumer = (operand, mode, flags) -> {
                         if (isVariable(operand)) {
                             int varNum = allocator.operandNumber(operand);
-                            liveKill.set(varNum);
+                            liveKillScratch.set(varNum);
                             if (debug.isLogEnabled()) {
                                 debug.log("liveKill for operand %d(%s)", varNum, operand);
                             }
@@ -217,7 +219,7 @@
                              * be processed in live sets. Process them only in debug mode so that
                              * this can be checked
                              */
-                            verifyTemp(liveKill, operand);
+                            verifyTemp(liveKillScratch, operand);
                         }
                     };
 
@@ -239,10 +241,11 @@
                     } // end of instruction iteration
 
                     BlockData blockSets = allocator.getBlockData(block);
-                    blockSets.liveGen = liveGen;
-                    blockSets.liveKill = liveKill;
-                    blockSets.liveIn = new BitSet(liveSize);
-                    blockSets.liveOut = new BitSet(liveSize);
+                    blockSets.liveGen = trimClone(liveGenScratch);
+                    blockSets.liveKill = trimClone(liveKillScratch);
+                    // sticky size, will get non-sticky in computeGlobalLiveSets
+                    blockSets.liveIn = new BitSet(0);
+                    blockSets.liveOut = new BitSet(0);
 
                     if (debug.isLogEnabled()) {
                         debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
@@ -292,7 +295,7 @@
             boolean changeOccurred;
             boolean changeOccurredInBlock;
             int iterationCount = 0;
-            BitSet liveOut = new BitSet(allocator.liveSetSize()); // scratch set for calculations
+            BitSet scratch = new BitSet(allocator.liveSetSize()); // scratch set for calculations
 
             /*
              * Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
@@ -315,22 +318,16 @@
                          */
                         int n = block.getSuccessorCount();
                         if (n > 0) {
-                            liveOut.clear();
+                            scratch.clear();
                             // block has successors
                             if (n > 0) {
                                 for (AbstractBlockBase<?> successor : block.getSuccessors()) {
-                                    liveOut.or(allocator.getBlockData(successor).liveIn);
+                                    scratch.or(allocator.getBlockData(successor).liveIn);
                                 }
                             }
 
-                            if (!blockSets.liveOut.equals(liveOut)) {
-                                /*
-                                 * A change occurred. Swap the old and new live out sets to avoid
-                                 * copying.
-                                 */
-                                BitSet temp = blockSets.liveOut;
-                                blockSets.liveOut = liveOut;
-                                liveOut = temp;
+                            if (!blockSets.liveOut.equals(scratch)) {
+                                blockSets.liveOut = trimClone(scratch);
 
                                 changeOccurred = true;
                                 changeOccurredInBlock = true;
@@ -344,13 +341,20 @@
                              *
                              * Note: liveIn has to be computed only in first iteration or if liveOut
                              * has changed!
+                             *
+                             * Note: liveIn set can only grow, never shrink. No need to clear it.
                              */
                             BitSet liveIn = blockSets.liveIn;
-                            liveIn.clear();
+                            /*
+                             * BitSet#or will call BitSet#ensureSize (since the bit set is of length
+                             * 0 initially) and set sticky to false
+                             */
                             liveIn.or(blockSets.liveOut);
                             liveIn.andNot(blockSets.liveKill);
                             liveIn.or(blockSets.liveGen);
 
+                            liveIn.clone(); // trimToSize()
+
                             if (debug.isLogEnabled()) {
                                 debug.log("block %d: livein = %s,  liveout = %s", block.getId(), liveIn, blockSets.liveOut);
                             }
@@ -384,6 +388,20 @@
         }
     }
 
+    /**
+     * Creates a trimmed copy a bit set.
+     *
+     * {@link BitSet#clone()} cannot be used since it will not {@linkplain BitSet#trimToSize trim}
+     * the array if the bit set is {@linkplain BitSet#sizeIsSticky sticky}.
+     */
+    @SuppressWarnings("javadoc")
+    private static BitSet trimClone(BitSet set) {
+        BitSet trimmedSet = new BitSet(0); // zero-length words array, sticky
+        trimmedSet.or(set); // words size ensured to be words-in-use of set,
+                            // also makes it non-sticky
+        return trimmedSet;
+    }
+
     @SuppressWarnings("try")
     protected void reportFailure(int numBlocks) {
         try (DebugContext.Scope s = debug.forceLog()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,26 +23,20 @@
 package org.graalvm.compiler.lir.alloc.lsra;
 
 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
+import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase;
 import org.graalvm.compiler.lir.alloc.lsra.ssa.SSALinearScan;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
-import org.graalvm.compiler.lir.phases.AllocationPhase;
 
 import jdk.vm.ci.code.TargetDescription;
 
-public final class LinearScanPhase extends AllocationPhase {
-
-    private boolean neverSpillConstants;
-
-    public void setNeverSpillConstants(boolean neverSpillConstants) {
-        this.neverSpillConstants = neverSpillConstants;
-    }
+public final class LinearScanPhase extends RegisterAllocationPhase {
 
     @Override
     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
         MoveFactory spillMoveFactory = context.spillMoveFactory;
         RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig;
-        final LinearScan allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, lirGenRes.getLIR().linearScanOrder(), neverSpillConstants);
+        final LinearScan allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, lirGenRes.getLIR().linearScanOrder(), getNeverSpillConstants());
         allocator.allocate(target, lirGenRes, context);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.lir.alloc.lsra;
 
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.debug.Indent;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/MoveResolver.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/MoveResolver.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,8 +28,8 @@
 
 import java.util.ArrayList;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,10 +30,10 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.Indent;
 import org.graalvm.compiler.lir.LIR;
+import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase;
 import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
-import org.graalvm.compiler.lir.phases.AllocationPhase;
 import org.graalvm.compiler.lir.ssa.SSAUtil;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
@@ -47,7 +47,7 @@
  * <a href="http://dx.doi.org/10.1145/2972206.2972211">"Trace-based Register Allocation in a JIT
  * Compiler"</a> by Josef Eisl et al.
  */
-public final class TraceRegisterAllocationPhase extends AllocationPhase {
+public final class TraceRegisterAllocationPhase extends RegisterAllocationPhase {
 
     public static class Options {
         // @formatter:off
@@ -67,9 +67,20 @@
     public static final CounterKey globalStackSlots = DebugContext.counter("TraceRA[GlobalStackSlots]");
     public static final CounterKey allocatedStackSlots = DebugContext.counter("TraceRA[AllocatedStackSlots]");
 
+    private final TraceBuilderPhase traceBuilder;
+    private final GlobalLivenessAnalysisPhase livenessAnalysis;
+
+    public TraceRegisterAllocationPhase() {
+        this.traceBuilder = new TraceBuilderPhase();
+        this.livenessAnalysis = new GlobalLivenessAnalysisPhase();
+    }
+
     @Override
     @SuppressWarnings("try")
     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
+        traceBuilder.apply(target, lirGenRes, context);
+        livenessAnalysis.apply(target, lirGenRes, context);
+
         MoveFactory spillMoveFactory = context.spillMoveFactory;
         RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig;
         LIR lir = lirGenRes.getLIR();
@@ -80,8 +91,8 @@
         TraceAllocationContext traceContext = new TraceAllocationContext(spillMoveFactory, registerAllocationConfig, resultTraces, livenessInfo);
         AllocatableValue[] cachedStackSlots = Options.TraceRACacheStackSlots.getValue(lir.getOptions()) ? new AllocatableValue[lir.numVariables()] : null;
 
-        // currently this is not supported
-        boolean neverSpillConstant = false;
+        boolean neverSpillConstant = getNeverSpillConstants();
+        assert !neverSpillConstant : "currently this is not supported";
 
         final TraceRegisterAllocationPolicy plan = DefaultTraceRegisterAllocationPolicy.allocationPolicy(target, lirGenRes, spillMoveFactory, registerAllocationConfig, cachedStackSlots, resultTraces,
                         neverSpillConstant, livenessInfo, lir.getOptions());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,8 +32,8 @@
 import java.util.List;
 import java.util.function.Consumer;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.asm.AbstractAddress;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.code.CompilationResult;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.lir.gen;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
 import org.graalvm.compiler.debug.DebugContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/PhiResolver.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/PhiResolver.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,8 +30,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.lir.LIRInsertionBuffer;
 import org.graalvm.compiler.lir.LIRInstruction;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,6 @@
 import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.lir.alloc.AllocationStageVerifier;
 import org.graalvm.compiler.lir.alloc.lsra.LinearScanPhase;
-import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessAnalysisPhase;
-import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase;
 import org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase;
 import org.graalvm.compiler.lir.dfa.LocationMarkerPhase;
 import org.graalvm.compiler.lir.dfa.MarkBasePointersPhase;
@@ -42,8 +40,6 @@
     public AllocationStage(OptionValues options) {
         appendPhase(new MarkBasePointersPhase());
         if (TraceRA.getValue(options)) {
-            appendPhase(new TraceBuilderPhase());
-            appendPhase(new GlobalLivenessAnalysisPhase());
             appendPhase(new TraceRegisterAllocationPhase());
         } else {
             appendPhase(new LinearScanPhase());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,6 @@
 import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
 
 import org.graalvm.compiler.lir.alloc.lsra.LinearScanPhase;
-import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessAnalysisPhase;
-import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase;
 import org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase;
 import org.graalvm.compiler.lir.dfa.LocationMarkerPhase;
 import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
@@ -36,8 +34,6 @@
 public class EconomyAllocationStage extends LIRPhaseSuite<AllocationContext> {
     public EconomyAllocationStage(OptionValues options) {
         if (TraceRA.getValue(options)) {
-            appendPhase(new TraceBuilderPhase());
-            appendPhase(new GlobalLivenessAnalysisPhase());
             appendPhase(new TraceRegisterAllocationPhase());
         } else {
             appendPhase(new LinearScanPhase());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/FixPointIntervalBuilder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/FixPointIntervalBuilder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,8 +31,8 @@
 import java.util.Deque;
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.debug.CounterKey;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,7 +35,7 @@
 import java.util.EnumSet;
 import java.util.PriorityQueue;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/util/GenericValueMap.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/util/GenericValueMap.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.lir.util;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 
 import jdk.vm.ci.meta.Value;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.util.UnsignedLong;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.loop.InductionVariable.Direction;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
@@ -223,34 +224,37 @@
         return loop.loopBegin().getOverflowGuard();
     }
 
+    @SuppressWarnings("try")
     public GuardingNode createOverFlowGuard() {
         GuardingNode overflowGuard = getOverFlowGuard();
         if (overflowGuard != null) {
             return overflowGuard;
         }
-        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
-        StructuredGraph graph = iv.valueNode().graph();
-        CompareNode cond; // we use a negated guard with a < condition to achieve a >=
-        ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
-        if (iv.direction() == Direction.Up) {
-            ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
-            if (oneOff) {
-                v1 = sub(graph, v1, one);
+        try (DebugCloseable position = loop.loopBegin().withNodeSourcePosition()) {
+            IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
+            StructuredGraph graph = iv.valueNode().graph();
+            CompareNode cond; // we use a negated guard with a < condition to achieve a >=
+            ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
+            if (iv.direction() == Direction.Up) {
+                ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
+                if (oneOff) {
+                    v1 = sub(graph, v1, one);
+                }
+                cond = graph.unique(new IntegerLessThanNode(v1, end));
+            } else {
+                assert iv.direction() == Direction.Down;
+                ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
+                if (oneOff) {
+                    v1 = add(graph, v1, one);
+                }
+                cond = graph.unique(new IntegerLessThanNode(end, v1));
             }
-            cond = graph.unique(new IntegerLessThanNode(v1, end));
-        } else {
-            assert iv.direction() == Direction.Down;
-            ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
-            if (oneOff) {
-                v1 = add(graph, v1, one);
-            }
-            cond = graph.unique(new IntegerLessThanNode(end, v1));
+            assert graph.getGuardsStage().allowsFloatingGuards();
+            overflowGuard = graph.unique(new GuardNode(cond, AbstractBeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true,
+                            JavaConstant.NULL_POINTER)); // TODO gd: use speculation
+            loop.loopBegin().setOverflowGuard(overflowGuard);
+            return overflowGuard;
         }
-        assert graph.getGuardsStage().allowsFloatingGuards();
-        overflowGuard = graph.unique(new GuardNode(cond, AbstractBeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true,
-                        JavaConstant.NULL_POINTER)); // TODO gd: use speculation
-        loop.loopBegin().setOverflowGuard(overflowGuard);
-        return overflowGuard;
     }
 
     public IntegerStamp getStamp() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,9 +26,9 @@
 import java.util.LinkedList;
 import java.util.Queue;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,7 +27,7 @@
 import java.util.Deque;
 import java.util.Iterator;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Graph.DuplicationReplacement;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentWhole.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentWhole.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.loop;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Graph;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,9 +27,9 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.LoopBeginNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EncodedGraph.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EncodedGraph.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.NodeClass;
 
 import jdk.vm.ci.meta.Assumptions;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FieldLocationIdentity.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FieldLocationIdentity.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import jdk.vm.ci.meta.JavaKind.FormatWithToString;
 
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ResolvedJavaField;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,9 +37,9 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.util.TypeReader;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,8 @@
 import java.util.Iterator;
 import java.util.Objects;
 
-import org.graalvm.collections.Pair;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.Pair;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.core.common.util.FrequencyEncoder;
 import org.graalvm.compiler.core.common.util.TypeConversion;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphSpeculationLog.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.nodes;
+
+import jdk.internal.vm.compiler.collections.EconomicMap;
+
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.SpeculationLog;
+
+/**
+ * A wrapper around a {@link SpeculationLog} instance.
+ *
+ * This should be used when the wrapped instance may be accessed by multiple threads. Due to races,
+ * such an instance can return true for a call to {@link SpeculationLog#maySpeculate} but still fail
+ * (i.e. raise an {@link IllegalArgumentException}) when {@link SpeculationLog#speculate} is called.
+ *
+ * A {@link GraphSpeculationLog} must only be used by a single thread and is typically closely
+ * coupled with a {@link StructuredGraph} (hence the name).
+ */
+public final class GraphSpeculationLog implements SpeculationLog {
+
+    private final SpeculationLog log;
+    private final EconomicMap<SpeculationReason, JavaConstant> speculations;
+
+    public GraphSpeculationLog(SpeculationLog log) {
+        this.log = log;
+        this.speculations = EconomicMap.create();
+    }
+
+    /**
+     * Unwraps {@code log} if it is a {@link GraphSpeculationLog}.
+     */
+    public static SpeculationLog unwrap(SpeculationLog log) {
+        if (log instanceof GraphSpeculationLog) {
+            return ((GraphSpeculationLog) log).log;
+        }
+        return log;
+    }
+
+    /**
+     * Determines if the compiler is allowed to speculate with {@code reason}. Note that a
+     * {@code true} return value guarantees that a subsequent call to
+     * {@link #speculate(SpeculationReason)} with an argument {@linkplain Object#equals(Object)
+     * equal} to {@code reason} will succeed.
+     */
+    @Override
+    public boolean maySpeculate(SpeculationReason reason) {
+        JavaConstant speculation = speculations.get(reason);
+        if (speculation == null) {
+            if (log.maySpeculate(reason)) {
+                try {
+                    speculation = log.speculate(reason);
+                    speculations.put(reason, speculation);
+                } catch (IllegalArgumentException e) {
+                    // The speculation was disabled by another thread in between
+                    // the call to log.maySpeculate and log.speculate
+                    speculation = null;
+                }
+            }
+        }
+        return speculation != null;
+    }
+
+    @Override
+    public JavaConstant speculate(SpeculationReason reason) {
+        if (maySpeculate(reason)) {
+            JavaConstant speculation = speculations.get(reason);
+            assert speculation != null;
+            return speculation;
+        }
+        throw new IllegalArgumentException("Cannot make speculation with reason " + reason + " as it is known to fail");
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof GraphSpeculationLog) {
+            GraphSpeculationLog that = (GraphSpeculationLog) obj;
+            return this.log == that.log;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return log.hashCode();
+    }
+
+    @Override
+    public void collectFailedSpeculations() {
+        log.collectFailedSpeculations();
+    }
+
+    /**
+     * Returns if this log has speculations.
+     *
+     * @return true if {@link #maySpeculate(SpeculationReason)} has ever returned {@code true} for
+     *         this object
+     */
+    @Override
+    public boolean hasSpeculations() {
+        return !speculations.isEmpty();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,8 +30,8 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,14 +24,12 @@
 
 import jdk.vm.ci.meta.MetaUtil;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.graalvm.compiler.core.common.GraalOptions;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.options.OptionValues;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -56,6 +54,8 @@
  * {@link #addDecision} to log negative decisions.
  */
 public class InliningLog {
+    private static final String TREE_NODE = "\u251c\u2500\u2500";
+    private static final String LAST_TREE_NODE = "\u2514\u2500\u2500";
 
     public static final class Decision {
         private final boolean positive;
@@ -88,7 +88,8 @@
 
         @Override
         public String toString() {
-            return String.format("<%s> %s: %s", phase, target != null ? target.format("%H.%n(%p)") : "", reason);
+            return String.format("<%s> %s: %s, %s", phase, target != null ? target.format("%H.%n(%p)") : "", positive ? "yes" : "no",
+                            reason);
         }
     }
 
@@ -114,9 +115,9 @@
 
         public String positionString() {
             if (parent == null) {
-                return "<root>";
+                return "compilation of " + target.format("%H.%n(%p)");
             }
-            return MetaUtil.appendLocation(new StringBuilder(100), parent.target, getBci()).toString();
+            return "at " + MetaUtil.appendLocation(new StringBuilder(100), parent.target, getBci()).toString();
         }
 
         public int getBci() {
@@ -126,13 +127,13 @@
 
     private final Callsite root;
     private final EconomicMap<Invokable, Callsite> leaves;
-    private final OptionValues options;
+    private final boolean enabled;
 
-    public InliningLog(ResolvedJavaMethod rootMethod, OptionValues options) {
+    public InliningLog(ResolvedJavaMethod rootMethod, boolean enabled) {
         this.root = new Callsite(null, null);
         this.root.target = rootMethod;
         this.leaves = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
-        this.options = options;
+        this.enabled = enabled;
     }
 
     /**
@@ -142,15 +143,22 @@
      * logged after replacing an {@link Invoke} with a graph. In this case, the node replacement map
      * and the {@link InliningLog} of the inlined graph must be provided.
      */
-    public void addDecision(Invokable invoke, boolean positive, String reason, String phase, EconomicMap<Node, Node> replacements, InliningLog calleeLog) {
+    public void addDecision(Invokable invoke, boolean positive, String phase, EconomicMap<Node, Node> replacements, InliningLog calleeLog, String reason, Object... args) {
+        if (!enabled) {
+            return;
+        }
         assert leaves.containsKey(invoke);
-        assert (!positive && replacements == null && calleeLog == null) || (positive && replacements != null && calleeLog != null);
+        assert (!positive && replacements == null && calleeLog == null) || (positive && replacements != null && calleeLog != null) ||
+                        (positive && replacements == null && calleeLog == null);
         Callsite callsite = leaves.get(invoke);
         callsite.target = callsite.invoke.getTargetMethod();
-        Decision decision = new Decision(positive, reason, phase, invoke.getTargetMethod());
+        Decision decision = new Decision(positive, String.format(reason, args), phase, invoke.getTargetMethod());
         callsite.decisions.add(decision);
         if (positive) {
             leaves.removeKey(invoke);
+            if (calleeLog == null) {
+                return;
+            }
             EconomicMap<Callsite, Callsite> mapping = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
             for (Callsite calleeChild : calleeLog.root.children) {
                 Callsite child = callsite.addChild(calleeChild.invoke);
@@ -227,7 +235,7 @@
         mapping.put(replacementSite, site);
         site.target = replacementSite.target;
         site.decisions.addAll(replacementSite.decisions);
-        site.invoke = replacementSite.invoke != null && replacementSite.invoke.asFixedNode().isAlive() ? (Invokable) replacements.get(replacementSite.invoke.asFixedNode()) : null;
+        site.invoke = replacementSite.invoke != null && replacementSite.invoke.isAlive() ? (Invokable) replacements.get(replacementSite.invoke.asFixedNode()) : null;
         for (Callsite replacementChild : replacementSite.children) {
             Callsite child = new Callsite(site, null);
             site.children.add(child);
@@ -253,7 +261,7 @@
     private UpdateScope noUpdates = new UpdateScope((oldNode, newNode) -> {
     });
 
-    private UpdateScope activated = null;
+    private UpdateScope currentUpdateScope = null;
 
     /**
      * Used to designate scopes in which {@link Invokable} registration or cloning should be handled
@@ -267,17 +275,17 @@
         }
 
         public void activate() {
-            if (activated != null) {
+            if (currentUpdateScope != null) {
                 throw GraalError.shouldNotReachHere("InliningLog updating already set.");
             }
-            activated = this;
+            currentUpdateScope = this;
         }
 
         @Override
         public void close() {
-            if (GraalOptions.TraceInlining.getValue(options)) {
-                assert activated != null;
-                activated = null;
+            if (enabled) {
+                assert currentUpdateScope != null;
+                currentUpdateScope = null;
             }
         }
 
@@ -287,10 +295,10 @@
     }
 
     public BiConsumer<Invokable, Invokable> getUpdateScope() {
-        if (activated == null) {
+        if (currentUpdateScope == null) {
             return null;
         }
-        return activated.getUpdater();
+        return currentUpdateScope.getUpdater();
     }
 
     /**
@@ -305,7 +313,7 @@
      * @return a bound {@link UpdateScope} object, or a {@code null} if tracing is disabled
      */
     public UpdateScope openUpdateScope(BiConsumer<Invokable, Invokable> updater) {
-        if (GraalOptions.TraceInlining.getValue(options)) {
+        if (enabled) {
             UpdateScope scope = new UpdateScope(updater);
             scope.activate();
             return scope;
@@ -324,7 +332,7 @@
      * @see #openUpdateScope
      */
     public UpdateScope openDefaultUpdateScope() {
-        if (GraalOptions.TraceInlining.getValue(options)) {
+        if (enabled) {
             noUpdates.activate();
             return noUpdates;
         } else {
@@ -332,6 +340,97 @@
         }
     }
 
+    private RootScope currentRootScope = null;
+
+    /**
+     * Used to change the current effective root of the method being compiled.
+     *
+     * This root scope is used in situations in which a phase does its own ad-hoc inlining, in which
+     * it replaces an Invoke with other nodes, some of which may be other Invokes. The prime example
+     * for this is the bytecode parser, which does not create separate graphs with their own
+     * inlining logs when inlining an Invoke, but instead continues recursively parsing the graph
+     * corresponding to the Invoke.
+     *
+     * Root scopes can be nested.
+     *
+     * @see #openRootScope
+     */
+    public final class RootScope implements AutoCloseable {
+        private final RootScope parent;
+        private Callsite replacementRoot;
+
+        public RootScope(RootScope parent, Callsite replacementRoot) {
+            this.parent = parent;
+            this.replacementRoot = replacementRoot;
+        }
+
+        void activate() {
+            currentRootScope = this;
+        }
+
+        public Invokable getInvoke() {
+            return replacementRoot.invoke;
+        }
+
+        @Override
+        public void close() {
+            if (enabled) {
+                assert currentRootScope != null;
+                removeLeafCallsite(replacementRoot.invoke);
+                currentRootScope = parent;
+            }
+        }
+    }
+
+    public final class PlaceholderInvokable implements Invokable {
+        private int bci;
+        private ResolvedJavaMethod method;
+
+        public PlaceholderInvokable(ResolvedJavaMethod method, int bci) {
+            this.method = method;
+            this.bci = bci;
+        }
+
+        @Override
+        public ResolvedJavaMethod getTargetMethod() {
+            return method;
+        }
+
+        @Override
+        public int bci() {
+            return bci;
+        }
+
+        @Override
+        public boolean isAlive() {
+            return false;
+        }
+
+        @Override
+        public FixedNode asFixedNode() {
+            throw new UnsupportedOperationException("Parsed invokable is a placeholder, not a concrete node.");
+        }
+    }
+
+    public RootScope openRootScope(ResolvedJavaMethod target, int bci) {
+        return openRootScope(new PlaceholderInvokable(target, bci));
+    }
+
+    public RootScope openRootScope(Invokable invoke) {
+        if (enabled) {
+            if (!leaves.containsKey(invoke)) {
+                // Create the invoke if it was not added to the graph yet.
+                trackNewCallsite(invoke);
+            }
+            RootScope scope = new RootScope(currentRootScope, leaves.get(invoke));
+            scope.replacementRoot.target = invoke.getTargetMethod();
+            scope.activate();
+            return scope;
+        } else {
+            return null;
+        }
+    }
+
     public boolean containsLeafCallsite(Invokable invokable) {
         return leaves.containsKey(invokable);
     }
@@ -342,11 +441,16 @@
 
     public void trackNewCallsite(Invokable invoke) {
         assert !leaves.containsKey(invoke);
-        Callsite callsite = new Callsite(root, invoke);
-        root.children.add(callsite);
+        Callsite currentRoot = findCurrentRoot();
+        Callsite callsite = new Callsite(currentRoot, invoke);
+        currentRoot.children.add(callsite);
         leaves.put(invoke, callsite);
     }
 
+    private Callsite findCurrentRoot() {
+        return currentRootScope != null ? currentRootScope.replacementRoot : root;
+    }
+
     public void trackDuplicatedCallsite(Invokable sibling, Invokable newInvoke) {
         Callsite siblingCallsite = leaves.get(sibling);
         Callsite parentCallsite = siblingCallsite.parent;
@@ -361,7 +465,19 @@
         callsite.invoke = newInvoke;
     }
 
-    public String formatAsTree() {
+    /**
+     * Formats the inlining log as a hierarchical tree.
+     *
+     * @param nullIfEmpty specifies whether null should be returned if there are no inlining
+     *            decisions
+     * @return the tree representation of the inlining log
+     */
+    public String formatAsTree(boolean nullIfEmpty) {
+        assert root.decisions.isEmpty();
+        assert !root.children.isEmpty() || leaves.isEmpty();
+        if (nullIfEmpty && root.children.isEmpty()) {
+            return null;
+        }
         StringBuilder builder = new StringBuilder(512);
         formatAsTree(root, "", builder);
         return builder.toString();
@@ -369,12 +485,20 @@
 
     private void formatAsTree(Callsite site, String indent, StringBuilder builder) {
         String position = site.positionString();
-        builder.append(indent).append("at ").append(position).append(": ");
+        builder.append(indent).append(position).append(": ");
         if (site.decisions.isEmpty()) {
+            if (site.parent != null) {
+                builder.append("(no decisions made about ").append(site.target != null ? site.target.format("%H.%n(%p)") : "").append(")");
+            }
+            builder.append(System.lineSeparator());
+        } else if (site.decisions.size() == 1) {
+            builder.append(site.decisions.get(0).toString());
             builder.append(System.lineSeparator());
         } else {
+            builder.append(System.lineSeparator());
             for (Decision decision : site.decisions) {
-                builder.append(decision.toString());
+                String node = (decision == site.decisions.get(site.decisions.size() - 1)) ? LAST_TREE_NODE : TREE_NODE;
+                builder.append(indent + "   " + node).append(decision.toString());
                 builder.append(System.lineSeparator());
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invokable.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invokable.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,6 +35,10 @@
 
     int bci();
 
+    default boolean isAlive() {
+        return asFixedNode().isAlive();
+    }
+
     FixedNode asFixedNode();
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -41,7 +41,7 @@
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
 import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import java.util.Map;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
 import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import java.util.Map;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/KillingBeginNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/KillingBeginNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo(allowedUsageTypes = {Memory}, cycles = CYCLES_0, size = SIZE_0)
 public final class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -105,9 +105,7 @@
         Node prev = this.predecessor();
         while (tool.allUsagesAvailable() && prev instanceof BeginNode && prev.hasNoUsages()) {
             AbstractBeginNode begin = (AbstractBeginNode) prev;
-            if (begin.getNodeSourcePosition() != null || this.getNodeSourcePosition() == null || this.getNodeSourcePosition().isPlaceholder()) {
-                this.setNodeSourcePosition(begin.getNodeSourcePosition());
-            }
+            this.setNodeSourcePosition(begin.getNodeSourcePosition());
             prev = prev.predecessor();
             graph().removeFixed(begin);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NamedLocationIdentity.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NamedLocationIdentity.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,9 +24,9 @@
 
 import java.util.EnumMap;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaKind.FormatWithToString;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StartNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StartNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * The start node of a graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,10 +30,10 @@
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.core.common.CancellationBailoutException;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.GraalOptions;
@@ -359,12 +359,16 @@
         this.compilationId = compilationId;
         this.entryBCI = entryBCI;
         this.assumptions = assumptions;
-        this.speculationLog = speculationLog;
+        if (speculationLog != null && !(speculationLog instanceof GraphSpeculationLog)) {
+            this.speculationLog = new GraphSpeculationLog(speculationLog);
+        } else {
+            this.speculationLog = speculationLog;
+        }
         this.useProfilingInfo = useProfilingInfo;
         this.trackNodeSourcePosition = trackNodeSourcePosition;
         assert trackNodeSourcePosition != null;
         this.cancellable = cancellable;
-        this.inliningLog = new InliningLog(rootMethod, options);
+        this.inliningLog = new InliningLog(rootMethod, GraalOptions.TraceInlining.getValue(options));
         this.callerContext = context;
     }
 
@@ -480,7 +484,10 @@
 
     public void logInliningTree() {
         if (GraalOptions.TraceInlining.getValue(getOptions())) {
-            TTY.println(getInliningLog().formatAsTree());
+            String formattedTree = getInliningLog().formatAsTree(true);
+            if (formattedTree != null) {
+                TTY.println(formattedTree);
+            }
         }
     }
 
@@ -518,6 +525,7 @@
         copy.isAfterFloatingReadPhase = isAfterFloatingReadPhase;
         copy.hasValueProxies = hasValueProxies;
         copy.isAfterExpandLogic = isAfterExpandLogic;
+        copy.trackNodeSourcePosition = trackNodeSourcePosition;
         EconomicMap<Node, Node> replacements = EconomicMap.create(Equivalence.IDENTITY);
         replacements.put(start, copy.start);
         UnmodifiableEconomicMap<Node, Node> duplicates;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public final class Block extends AbstractBlockBase<Block> {
     public static final Block[] EMPTY_ARRAY = new Block[0];
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/HIRLoop.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/HIRLoop.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.nodes.LoopBeginNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public final class HIRLoop extends Loop<Block> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/LocationSet.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/LocationSet.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public class LocationSet {
     private LocationIdentity firstLocation;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/StringToBytesNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/StringToBytesNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -46,7 +46,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,7 +27,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaReadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaReadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,7 +32,7 @@
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Creates a memory barrier.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -44,7 +44,7 @@
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.Constant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeAccessNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeAccessNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,7 +35,7 @@
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.type.StampTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeCopyNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeCopyNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,7 +26,7 @@
 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryLoadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryLoadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,7 +32,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryStoreNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryStoreNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,15 +35,16 @@
 import java.util.List;
 import java.util.Map;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.Pair;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.Pair;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitutionRegistry;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
+import org.graalvm.compiler.core.common.SuppressFBWarnings;
 import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
@@ -862,6 +863,7 @@
         lateRegistrations = lateClassPlugins;
     }
 
+    @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "string literal object identity used as sentinel")
     private synchronized boolean closeLateRegistrations() {
         if (lateRegistrations == null || lateRegistrations.className != CLOSED_LATE_CLASS_PLUGIN) {
             lateRegistrations = new LateClassPlugins(lateRegistrations, CLOSED_LATE_CLASS_PLUGIN);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.memory.LIRLowerableAccess;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Low-level atomic compare-and-swap operation.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Value;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,7 +34,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Value;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * The {@code MonitorEnterNode} represents the acquisition of a monitor.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * The {@code MonitorExitNode} represents a monitor release. If it is the release of the monitor of
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,7 +38,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * The {@code RawMonitorEnterNode} represents the acquisition of a monitor. The object needs to
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
@@ -53,8 +53,8 @@
     @Input ValueNode expected;
     @Input ValueNode newValue;
 
-    protected final JavaKind valueKind;
-    protected final LocationIdentity locationIdentity;
+    private final JavaKind valueKind;
+    private final LocationIdentity locationIdentity;
 
     public UnsafeCompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, JavaKind valueKind, LocationIdentity locationIdentity) {
         super(TYPE, StampFactory.forKind(JavaKind.Boolean.getStackKind()));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,7 +32,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * A special purpose store node that differs from {@link LogicCompareAndSwapNode} in that it returns
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Guard}, cycles = CYCLES_2, size = SIZE_1)
 public abstract class AbstractWriteNode extends FixedAccessNode implements StateSplit, MemoryCheckpoint.Single, MemoryAccess, GuardingNode {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import org.graalvm.compiler.nodes.extended.GuardedNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public interface Access extends GuardedNode, HeapAccess {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -31,7 +31,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Accesses a value at an memory address specified by an {@linkplain #address address}. The access
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,7 +28,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * An {@link FixedAccessNode} that can be converted to a {@link FloatingAccessNode}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,7 +29,7 @@
 import org.graalvm.compiler.nodes.FloatingGuardedNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo
 public abstract class FloatingAccessNode extends FloatingGuardedNode implements Access, MemoryAccess {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -41,7 +41,7 @@
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * A floating read of a value from memory specified in terms of an object base and an object
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryAccess.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryAccess.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes.memory;
 
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * This interface marks nodes that access some memory location, and that have an edge to the last
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryCheckpoint.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryCheckpoint.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedNodeInterface;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * This interface marks subclasses of {@link FixedNode} that kill a set of memory locations
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMap.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMap.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes.memory;
 
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Maps a {@linkplain LocationIdentity location} to the last node that (potentially) wrote to the
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMapNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryMapNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,15 +26,15 @@
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
@@ -44,7 +44,7 @@
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo(allowedUsageTypes = {Extension, Memory}, cycles = CYCLES_0, size = SIZE_0)
 public final class MemoryMapNode extends FloatingNode implements MemoryMap, MemoryNode, LIRLowerable {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,7 +30,7 @@
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Memory {@code PhiNode}s merge memory dependencies at control flow merges.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -48,7 +48,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.MetaAccessProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * Writes a given {@linkplain #value() value} a {@linkplain FixedAccessNode memory location}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/MemoryProxy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/MemoryProxy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,7 +23,7 @@
 package org.graalvm.compiler.nodes.spi;
 
 import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public interface MemoryProxy extends Proxy, MemoryNode {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,10 +30,10 @@
 import java.util.List;
 import java.util.function.BiFunction;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.code.SourceStackTraceBailoutException;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -54,7 +54,7 @@
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.nodes.spi.VirtualizableAllocation;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 // @formatter:off
 @NodeInfo(nameTemplate = "Alloc {i#virtualObjects}",
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Tue Apr 24 09:04:57 2018 -0700
@@ -61,6 +61,7 @@
 import org.graalvm.compiler.options.OptionDescriptor;
 import org.graalvm.compiler.options.OptionDescriptors;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
 
 /**
  * Processes static fields annotated with {@link Option}. An {@link OptionDescriptors}
@@ -218,7 +219,7 @@
             }
         }
 
-        info.options.add(new OptionInfo(optionName, help, extraHelp, optionType, declaringClass, field));
+        info.options.add(new OptionInfo(optionName, annotation.type(), help, extraHelp, optionType, declaringClass, field));
     }
 
     private void createFiles(OptionsInfo info) {
@@ -243,6 +244,7 @@
             out.println("");
             out.println("import java.util.*;");
             out.println("import " + OptionDescriptors.class.getPackage().getName() + ".*;");
+            out.println("import " + OptionType.class.getName() + ";");
             out.println("");
             out.println("public class " + optionsClassName + " implements " + OptionDescriptors.class.getSimpleName() + " {");
 
@@ -263,6 +265,7 @@
                     optionField = option.declaringClass + "." + option.field.getSimpleName();
                 }
                 out.println("        case \"" + name + "\": {");
+                OptionType optionType = option.optionType;
                 String type = option.type;
                 String help = option.help;
                 String[] extraHelp = option.extraHelp;
@@ -270,7 +273,8 @@
                 Name fieldName = option.field.getSimpleName();
                 out.printf("            return " + desc + ".create(\n");
                 out.printf("                /*name*/ \"%s\",\n", name);
-                out.printf("                /*type*/ %s.class,\n", type);
+                out.printf("                /*optionType*/ %s.%s,\n", optionType.getDeclaringClass().getSimpleName(), optionType.name());
+                out.printf("                /*optionValueType*/ %s.class,\n", type);
                 out.printf("                /*help*/ \"%s\",\n", help);
                 if (extraHelp.length != 0) {
                     out.printf("                /*extraHelp*/ new String[] {\n");
@@ -332,14 +336,16 @@
     static class OptionInfo implements Comparable<OptionInfo> {
 
         final String name;
+        final OptionType optionType;
         final String help;
         final String[] extraHelp;
         final String type;
         final String declaringClass;
         final VariableElement field;
 
-        OptionInfo(String name, String help, String[] extraHelp, String type, String declaringClass, VariableElement field) {
+        OptionInfo(String name, OptionType optionType, String help, String[] extraHelp, String type, String declaringClass, VariableElement field) {
             this.name = name;
+            this.optionType = optionType;
             this.help = help;
             this.extraHelp = extraHelp;
             this.type = type;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/NestedBooleanOptionKeyTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/NestedBooleanOptionKeyTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.options.NestedBooleanOptionKey;
 import org.graalvm.compiler.options.OptionDescriptor;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 import org.junit.Test;
 
@@ -54,12 +55,12 @@
         public static final OptionKey<Boolean> NestedOption2 = new NestedBooleanOptionKey(Master2, false);
     }
 
-    static final OptionDescriptor master0 = OptionDescriptor.create("Master0", Boolean.class, "", Options.class, "Master0", Master0);
-    static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0);
-    static final OptionDescriptor master1 = OptionDescriptor.create("Master1", Boolean.class, "", Options.class, "Master1", Master1);
-    static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1);
-    static final OptionDescriptor master2 = OptionDescriptor.create("Master2", Boolean.class, "", Options.class, "Master2", Master2);
-    static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2);
+    static final OptionDescriptor master0 = OptionDescriptor.create("Master0", OptionType.Debug, Boolean.class, "", Options.class, "Master0", Master0);
+    static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", OptionType.Debug, Boolean.class, "", Options.class, "NestedOption0", NestedOption0);
+    static final OptionDescriptor master1 = OptionDescriptor.create("Master1", OptionType.Debug, Boolean.class, "", Options.class, "Master1", Master1);
+    static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", OptionType.Debug, Boolean.class, "", Options.class, "NestedOption1", NestedOption1);
+    static final OptionDescriptor master2 = OptionDescriptor.create("Master2", OptionType.Debug, Boolean.class, "", Options.class, "Master2", Master2);
+    static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", OptionType.Debug, Boolean.class, "", Options.class, "NestedOption2", NestedOption2);
 
     @Test
     public void runDefaultTrue() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/TestOptionKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.test/src/org/graalvm/compiler/options/test/TestOptionKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.options.ModifiableOptionValues;
 import org.graalvm.compiler.options.OptionDescriptor;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 import org.junit.Assert;
 import org.junit.Assume;
@@ -51,7 +52,7 @@
 
     @Test
     public void toStringTest() {
-        OptionDescriptor.create("MyOption", String.class, "", Options.class, "MyOption", MyOption);
+        OptionDescriptor.create("MyOption", OptionType.Debug, String.class, "", Options.class, "MyOption", MyOption);
         assertEquals("MyOption", MyOption.toString());
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.EnumSet;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 
 public class EnumOptionKey<T extends Enum<T>> extends OptionKey<T> {
     final Class<T> enumClass;
@@ -45,11 +45,11 @@
         return EnumSet.allOf(enumClass);
     }
 
-    Object valueOf(String name) {
+    public Object valueOf(String name) {
         try {
             return Enum.valueOf(enumClass, name);
         } catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException("\"" + name + "\" is not a valid option for " + getName() + ". Valid values are " + EnumSet.allOf(enumClass));
+            throw new IllegalArgumentException("\"" + name + "\" is not a valid option for " + getName() + ". Valid values are " + getAllValues());
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/ModifiableOptionValues.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/ModifiableOptionValues.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,10 +24,10 @@
 
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 
 /**
  * A context for obtaining values for {@link OptionKey}s that allows for key/value pairs to be
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,8 @@
 public final class OptionDescriptor {
 
     protected final String name;
-    protected final Class<?> type;
+    protected final OptionType optionType;
+    protected final Class<?> optionValueType;
     protected final String help;
     protected final List<String> extraHelp;
     protected final OptionKey<?> optionKey;
@@ -42,39 +43,41 @@
 
     private static final String[] NO_EXTRA_HELP = {};
 
-    public static OptionDescriptor create(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
-        return create(name, type, help, NO_EXTRA_HELP, declaringClass, fieldName, option);
+    public static OptionDescriptor create(String name, OptionType optionType, Class<?> optionValueType, String help, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
+        return create(name, optionType, optionValueType, help, NO_EXTRA_HELP, declaringClass, fieldName, option);
     }
 
-    public static OptionDescriptor create(String name, Class<?> type, String help, String[] extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
+    public static OptionDescriptor create(String name, OptionType optionType, Class<?> optionValueType, String help, String[] extraHelp, Class<?> declaringClass, String fieldName,
+                    OptionKey<?> option) {
         assert option != null : declaringClass + "." + fieldName;
         OptionDescriptor result = option.getDescriptor();
         if (result == null) {
             List<String> extraHelpList = extraHelp == null || extraHelp.length == 0 ? Collections.emptyList() : Collections.unmodifiableList(Arrays.asList(extraHelp));
-            result = new OptionDescriptor(name, type, help, extraHelpList, declaringClass, fieldName, option);
+            result = new OptionDescriptor(name, optionType, optionValueType, help, extraHelpList, declaringClass, fieldName, option);
             option.setDescriptor(result);
         }
-        assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.optionKey == option;
+        assert result.name.equals(name) && result.optionValueType == optionValueType && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.optionKey == option;
         return result;
     }
 
-    private OptionDescriptor(String name, Class<?> type, String help, List<String> extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> optionKey) {
+    private OptionDescriptor(String name, OptionType optionType, Class<?> optionValueType, String help, List<String> extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> optionKey) {
         this.name = name;
-        this.type = type;
+        this.optionType = optionType;
+        this.optionValueType = optionValueType;
         this.help = help;
         this.extraHelp = extraHelp;
         this.optionKey = optionKey;
         this.declaringClass = declaringClass;
         this.fieldName = fieldName;
-        assert !type.isPrimitive() : "must used boxed type instead of " + type;
+        assert !optionValueType.isPrimitive() : "must used boxed optionValueType instead of " + optionValueType;
     }
 
     /**
      * Gets the type of values stored in the option. This will be the boxed type for a primitive
      * option.
      */
-    public Class<?> getType() {
-        return type;
+    public Class<?> getOptionValueType() {
+        return optionValueType;
     }
 
     /**
@@ -104,6 +107,13 @@
     }
 
     /**
+     * Gets the type of the option.
+     */
+    public OptionType getOptionType() {
+        return optionType;
+    }
+
+    /**
      * Gets the boxed option value.
      */
     public OptionKey<?> getOptionKey() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.Formatter;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 
 /**
  * A key for an option. The value for an option is obtained from an {@link OptionValues} object.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,10 +30,10 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 
 /**
  * A context for obtaining values for {@link OptionKey}s.
@@ -126,7 +126,7 @@
     /**
      * Decodes a value that may be the sentinel value for {@code null} in a map.
      */
-    protected static Object decodeNull(Object value) {
+    public static Object decodeNull(Object value) {
         return value == NULL ? null : value;
     }
 
@@ -212,7 +212,7 @@
 
             String name = namePrefix + e.getKey();
             String assign = containsKey(desc.optionKey) ? ":=" : "=";
-            String typeName = desc.getOptionKey() instanceof EnumOptionKey ? "String" : desc.getType().getSimpleName();
+            String typeName = desc.getOptionKey() instanceof EnumOptionKey ? "String" : desc.getOptionValueType().getSimpleName();
             String linePrefix = String.format("%s %s %s ", name, assign, value);
             int typeStartPos = PROPERTY_LINE_WIDTH - typeName.length();
             int linePad = typeStartPos - linePrefix.length();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValuesAccess.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.options;
-
-/**
- * Defines a service that supplies values for options. The values supplied may come from a source
- * such as system properties or a command line.
- *
- * This mechanism for obtaining option values must only be used if there is no other more local
- * context from which option values can be obtained.
- */
-public interface OptionValuesAccess {
-
-    /**
-     * Gets the option values available via this service.
-     */
-    OptionValues getOptions();
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,8 +28,8 @@
 import java.util.List;
 import java.util.ServiceLoader;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.util.CollectionsUtil;
 
 /**
@@ -116,7 +116,7 @@
      * @param loader source of the available {@link OptionDescriptors}
      * @throws IllegalArgumentException if there's a problem parsing {@code option}
      */
-    static void parseOption(String name, Object uncheckedValue, EconomicMap<OptionKey<?>, Object> values, Iterable<OptionDescriptors> loader) {
+    public static void parseOption(String name, Object uncheckedValue, EconomicMap<OptionKey<?>, Object> values, Iterable<OptionDescriptors> loader) {
 
         OptionDescriptor desc = lookup(loader, name);
         if (desc == null) {
@@ -132,7 +132,7 @@
             throw new IllegalArgumentException(msg.toString());
         }
 
-        Class<?> optionType = desc.getType();
+        Class<?> optionType = desc.getOptionValueType();
         Object value;
         if (!(uncheckedValue instanceof String)) {
             if (optionType != uncheckedValue.getClass()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -93,7 +93,7 @@
             } else {
                 continue;
             }
-            // the lowered address amy already be a replacement
+            // the lowered address may already be a replacement
             // in which case we want to use it not delete it!
             if (lowered != address) {
                 // replace original with lowered at this usage only
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -314,7 +314,7 @@
 
         @SuppressWarnings("try")
         public boolean tryCanonicalize(final Node node, NodeClass<?> nodeClass) {
-            try (DebugCloseable position = node.withNodeSourcePosition()) {
+            try (DebugCloseable position = node.withNodeSourcePosition(); DebugContext.Scope scope = debug.scope("tryCanonicalize", node)) {
                 if (customCanonicalizer != null) {
                     Node canonical = customCanonicalizer.canonicalize(node);
                     if (performReplacement(node, canonical)) {
@@ -349,6 +349,8 @@
                     return node.isDeleted();
                 }
                 return false;
+            } catch (Throwable throwable) {
+                throw debug.handle(throwable);
             }
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,10 +28,10 @@
 import java.util.Deque;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.FloatStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
@@ -51,6 +52,7 @@
     private static final double EPSILON = 1E-6;
 
     @Override
+    @SuppressWarnings("try")
     protected void run(StructuredGraph graph) {
         for (ShortCircuitOrNode logic : graph.getNodes(ShortCircuitOrNode.TYPE)) {
             processBinary(logic);
@@ -58,7 +60,9 @@
         assert graph.getNodes(ShortCircuitOrNode.TYPE).isEmpty();
 
         for (NormalizeCompareNode logic : graph.getNodes(NormalizeCompareNode.TYPE)) {
-            processNormalizeCompareNode(logic);
+            try (DebugCloseable context = logic.withNodeSourcePosition()) {
+                processNormalizeCompareNode(logic);
+            }
         }
         graph.setAfterExpandLogic();
     }
@@ -84,76 +88,83 @@
         normalize.replaceAtUsagesAndDelete(value);
     }
 
+    @SuppressWarnings("try")
     private static void processBinary(ShortCircuitOrNode binary) {
         while (binary.usages().isNotEmpty()) {
             Node usage = binary.usages().first();
-            if (usage instanceof ShortCircuitOrNode) {
-                processBinary((ShortCircuitOrNode) usage);
-            } else if (usage instanceof IfNode) {
-                processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, binary.getShortCircuitProbability());
-            } else if (usage instanceof ConditionalNode) {
-                processConditional(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (ConditionalNode) usage);
-            } else {
-                throw GraalError.shouldNotReachHere();
+            try (DebugCloseable nsp = usage.withNodeSourcePosition()) {
+                if (usage instanceof ShortCircuitOrNode) {
+                    processBinary((ShortCircuitOrNode) usage);
+                } else if (usage instanceof IfNode) {
+                    processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, binary.getShortCircuitProbability());
+                } else if (usage instanceof ConditionalNode) {
+                    processConditional(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (ConditionalNode) usage);
+                } else {
+                    throw GraalError.shouldNotReachHere();
+                }
             }
         }
         binary.safeDelete();
     }
 
+    @SuppressWarnings("try")
     private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) {
-        /*
-         * this method splits an IfNode, which has a ShortCircuitOrNode as its condition, into two
-         * separate IfNodes: if(X) and if(Y)
-         *
-         * for computing the probabilities P(X) and P(Y), we use two different approaches. The first
-         * one assumes that the shortCircuitProbability and the probability on the IfNode were
-         * created with each other in mind. If this assumption does not hold, we fall back to
-         * another mechanism for computing the probabilities.
-         */
-        AbstractBeginNode trueTarget = ifNode.trueSuccessor();
-        AbstractBeginNode falseTarget = ifNode.falseSuccessor();
-
-        // 1st approach
-        // assumption: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) * P(Y))
-        double firstIfTrueProbability = shortCircuitProbability;
-        double secondIfTrueProbability = sanitizeProbability((ifNode.getTrueSuccessorProbability() - shortCircuitProbability) / (1 - shortCircuitProbability));
-        double expectedOriginalIfTrueProbability = firstIfTrueProbability + (1 - firstIfTrueProbability) * secondIfTrueProbability;
-
-        if (!doubleEquals(ifNode.getTrueSuccessorProbability(), expectedOriginalIfTrueProbability)) {
+        try (DebugCloseable context = ifNode.withNodeSourcePosition()) {
             /*
-             * 2nd approach
-             *
-             * the assumption above did not hold, so we either used an artificial probability as
-             * shortCircuitProbability or the ShortCircuitOrNode was moved to some other IfNode.
+             * this method splits an IfNode, which has a ShortCircuitOrNode as its condition, into
+             * two separate IfNodes: if(X) and if(Y)
              *
-             * so, we distribute the if's trueSuccessorProbability between the newly generated if
-             * nodes according to the shortCircuitProbability. the following invariant is always
-             * true in this case: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) * P(Y))
+             * for computing the probabilities P(X) and P(Y), we use two different approaches. The
+             * first one assumes that the shortCircuitProbability and the probability on the IfNode
+             * were created with each other in mind. If this assumption does not hold, we fall back
+             * to another mechanism for computing the probabilities.
              */
-            firstIfTrueProbability = ifNode.getTrueSuccessorProbability() * shortCircuitProbability;
-            secondIfTrueProbability = sanitizeProbability(1 - (ifNode.probability(falseTarget) / (1 - firstIfTrueProbability)));
-        }
+            AbstractBeginNode trueTarget = ifNode.trueSuccessor();
+            AbstractBeginNode falseTarget = ifNode.falseSuccessor();
+
+            // 1st approach
+            // assumption: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) * P(Y))
+            double firstIfTrueProbability = shortCircuitProbability;
+            double secondIfTrueProbability = sanitizeProbability((ifNode.getTrueSuccessorProbability() - shortCircuitProbability) / (1 - shortCircuitProbability));
+            double expectedOriginalIfTrueProbability = firstIfTrueProbability + (1 - firstIfTrueProbability) * secondIfTrueProbability;
 
-        ifNode.clearSuccessors();
-        Graph graph = ifNode.graph();
-        AbstractMergeNode trueTargetMerge = graph.add(new MergeNode());
-        trueTargetMerge.setNext(trueTarget);
-        EndNode firstTrueEnd = graph.add(new EndNode());
-        EndNode secondTrueEnd = graph.add(new EndNode());
-        trueTargetMerge.addForwardEnd(firstTrueEnd);
-        trueTargetMerge.addForwardEnd(secondTrueEnd);
-        AbstractBeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
-        AbstractBeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
-        if (yNegated) {
-            secondIfTrueProbability = 1.0 - secondIfTrueProbability;
+            if (!doubleEquals(ifNode.getTrueSuccessorProbability(), expectedOriginalIfTrueProbability)) {
+                /*
+                 * 2nd approach
+                 *
+                 * the assumption above did not hold, so we either used an artificial probability as
+                 * shortCircuitProbability or the ShortCircuitOrNode was moved to some other IfNode.
+                 *
+                 * so, we distribute the if's trueSuccessorProbability between the newly generated
+                 * if nodes according to the shortCircuitProbability. the following invariant is
+                 * always true in this case: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) *
+                 * P(Y))
+                 */
+                firstIfTrueProbability = ifNode.getTrueSuccessorProbability() * shortCircuitProbability;
+                secondIfTrueProbability = sanitizeProbability(1 - (ifNode.probability(falseTarget) / (1 - firstIfTrueProbability)));
+            }
+
+            ifNode.clearSuccessors();
+            Graph graph = ifNode.graph();
+            AbstractMergeNode trueTargetMerge = graph.add(new MergeNode());
+            trueTargetMerge.setNext(trueTarget);
+            EndNode firstTrueEnd = graph.add(new EndNode());
+            EndNode secondTrueEnd = graph.add(new EndNode());
+            trueTargetMerge.addForwardEnd(firstTrueEnd);
+            trueTargetMerge.addForwardEnd(secondTrueEnd);
+            AbstractBeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
+            AbstractBeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
+            if (yNegated) {
+                secondIfTrueProbability = 1.0 - secondIfTrueProbability;
+            }
+            if (xNegated) {
+                firstIfTrueProbability = 1.0 - firstIfTrueProbability;
+            }
+            AbstractBeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfTrueProbability)));
+            IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfTrueProbability));
+            ifNode.replaceAtPredecessor(firstIf);
+            ifNode.safeDelete();
         }
-        if (xNegated) {
-            firstIfTrueProbability = 1.0 - firstIfTrueProbability;
-        }
-        AbstractBeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfTrueProbability)));
-        IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfTrueProbability));
-        ifNode.replaceAtPredecessor(firstIf);
-        ifNode.safeDelete();
     }
 
     private static boolean doubleEquals(double a, double b) {
@@ -169,13 +180,16 @@
         return newValue;
     }
 
+    @SuppressWarnings("try")
     private static void processConditional(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, ConditionalNode conditional) {
-        ValueNode trueTarget = conditional.trueValue();
-        ValueNode falseTarget = conditional.falseValue();
-        Graph graph = conditional.graph();
-        ConditionalNode secondConditional = graph.unique(new ConditionalNode(y, yNegated ? falseTarget : trueTarget, yNegated ? trueTarget : falseTarget));
-        ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? secondConditional : trueTarget, xNegated ? trueTarget : secondConditional));
-        conditional.replaceAndDelete(firstConditional);
+        try (DebugCloseable context = conditional.withNodeSourcePosition()) {
+            ValueNode trueTarget = conditional.trueValue();
+            ValueNode falseTarget = conditional.falseValue();
+            Graph graph = conditional.graph();
+            ConditionalNode secondConditional = graph.unique(new ConditionalNode(y, yNegated ? falseTarget : trueTarget, yNegated ? trueTarget : falseTarget));
+            ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? secondConditional : trueTarget, xNegated ? trueTarget : secondConditional));
+            conditional.replaceAndDelete(firstConditional);
+        }
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,8 @@
  */
 package org.graalvm.compiler.phases.common;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.core.common.type.FloatStamp;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,16 +24,16 @@
 
 import static org.graalvm.compiler.graph.Graph.NodeEvent.NODE_ADDED;
 import static org.graalvm.compiler.graph.Graph.NodeEvent.ZERO_USAGES;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
@@ -71,7 +71,7 @@
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.LoopInfo;
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public class FloatingReadPhase extends Phase {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -75,7 +75,7 @@
 import org.graalvm.compiler.phases.Phase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.DeoptimizationAction;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,9 +22,9 @@
  */
 package org.graalvm.compiler.phases.common;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.graph.NodeStack;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,11 +33,11 @@
 import java.util.Objects;
 import java.util.function.Consumer;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.core.common.GraalOptions;
@@ -45,6 +45,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
 import org.graalvm.compiler.core.common.util.Util;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.GraalGraphError;
@@ -340,7 +341,13 @@
      */
     @SuppressWarnings("try")
     public static UnmodifiableEconomicMap<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod) {
-        return inline(invoke, inlineGraph, receiverNullCheck, inlineeMethod, "", "");
+        try {
+            return inline(invoke, inlineGraph, receiverNullCheck, inlineeMethod, "reason not specified", "phase not specified");
+        } catch (GraalError ex) {
+            ex.addContext("inlining into", invoke.asNode().graph().method());
+            ex.addContext("inlinee", inlineGraph.method());
+            throw ex;
+        }
     }
 
     /**
@@ -423,7 +430,7 @@
         try (InliningLog.UpdateScope scope = graph.getInliningLog().openDefaultUpdateScope()) {
             duplicates = graph.addDuplicates(nodes, inlineGraph, inlineGraph.getNodeCount(), localReplacement);
             if (scope != null) {
-                graph.getInliningLog().addDecision(invoke, true, reason, phase, duplicates, inlineGraph.getInliningLog());
+                graph.getInliningLog().addDecision(invoke, true, phase, duplicates, inlineGraph.getInliningLog(), reason);
             }
         }
 
@@ -491,13 +498,8 @@
      * @return the set of nodes to canonicalize
      */
     @SuppressWarnings("try")
-    public static EconomicSet<Node> inlineForCanonicalization(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod) {
-        return inlineForCanonicalization(invoke, inlineGraph, receiverNullCheck, inlineeMethod, null);
-    }
-
-    public static EconomicSet<Node> inlineForCanonicalization(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod,
-                    Consumer<UnmodifiableEconomicMap<Node, Node>> duplicatesConsumer) {
-        return inlineForCanonicalization(invoke, inlineGraph, receiverNullCheck, inlineeMethod, duplicatesConsumer, "", "");
+    public static EconomicSet<Node> inlineForCanonicalization(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod, String reason, String phase) {
+        return inlineForCanonicalization(invoke, inlineGraph, receiverNullCheck, inlineeMethod, null, reason, phase);
     }
 
     @SuppressWarnings("try")
@@ -684,28 +686,42 @@
         newNodes.addAll(invokeGraph.getNewNodes(mark));
         EconomicMap<NodeSourcePosition, NodeSourcePosition> posMap = EconomicMap.create(Equivalence.DEFAULT);
         UnmodifiableMapCursor<Node, Node> cursor = duplicates.getEntries();
+        ResolvedJavaMethod inlineeRoot = null;
         while (cursor.advance()) {
-            if (!newNodes.contains(cursor.getValue())) {
+            Node value = cursor.getValue();
+            if (!newNodes.contains(value)) {
                 continue;
             }
-            NodeSourcePosition pos = cursor.getKey().getNodeSourcePosition();
-            if (pos != null) {
-                NodeSourcePosition callerPos = posMap.get(pos);
-                if (callerPos == null) {
-                    callerPos = pos.addCaller(invokePos, isSubstitution);
-                    posMap.put(pos, callerPos);
-                }
-                cursor.getValue().setNodeSourcePosition(callerPos);
+            if (isSubstitution && invokePos == null) {
+                // There's no caller information so the source position for this node will be
+                // invalid, so it should be cleared.
+                value.clearNodeSourcePosition();
             } else {
-                if (isSubstitution) {
-                    /*
-                     * If no other position is provided at least attribute the substituted node to
-                     * the original invoke.
-                     */
-                    cursor.getValue().setNodeSourcePosition(invokePos);
+                NodeSourcePosition pos = cursor.getKey().getNodeSourcePosition();
+                if (pos != null) {
+                    if (inlineeRoot == null) {
+                        assert (inlineeRoot = pos.getRootMethod()) != null;
+                    } else {
+                        assert pos.verifyRootMethod(inlineeRoot);
+                    }
+                    NodeSourcePosition callerPos = posMap.get(pos);
+                    if (callerPos == null) {
+                        callerPos = pos.addCaller(invokePos, isSubstitution);
+                        posMap.put(pos, callerPos);
+                    }
+                    value.setNodeSourcePosition(callerPos);
+                } else {
+                    if (isSubstitution) {
+                        /*
+                         * If no other position is provided at least attribute the substituted node
+                         * to the original invoke.
+                         */
+                        value.setNodeSourcePosition(invokePos);
+                    }
                 }
             }
         }
+        assert invokeGraph.verifySourcePositions();
     }
 
     public static void processMonitorId(FrameState stateAfter, MonitorIdNode monitorIdNode) {
@@ -942,37 +958,42 @@
      * Gets the receiver for an invoke, adding a guard if necessary to ensure it is non-null, and
      * ensuring that the resulting type is compatible with the method being invoked.
      */
+    @SuppressWarnings("try")
     public static ValueNode nonNullReceiver(Invoke invoke) {
-        MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
-        assert !callTarget.isStatic() : callTarget.targetMethod();
-        StructuredGraph graph = callTarget.graph();
-        ValueNode oldReceiver = callTarget.arguments().get(0);
-        ValueNode newReceiver = oldReceiver;
-        if (newReceiver.getStackKind() == JavaKind.Object) {
+        try (DebugCloseable position = invoke.asNode().withNodeSourcePosition()) {
+            MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+            assert !callTarget.isStatic() : callTarget.targetMethod();
+            StructuredGraph graph = callTarget.graph();
+            ValueNode oldReceiver = callTarget.arguments().get(0);
+            ValueNode newReceiver = oldReceiver;
+            if (newReceiver.getStackKind() == JavaKind.Object) {
 
-            if (invoke.getInvokeKind() == InvokeKind.Special) {
-                Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
-                Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
-                if (!stamp.equals(paramStamp)) {
-                    // The verifier and previous optimizations guarantee unconditionally that the
-                    // receiver is at least of the type of the method holder for a special invoke.
-                    newReceiver = graph.unique(new PiNode(newReceiver, stamp));
+                if (invoke.getInvokeKind() == InvokeKind.Special) {
+                    Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
+                    Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
+                    if (!stamp.equals(paramStamp)) {
+                        // The verifier and previous optimizations guarantee unconditionally that
+                        // the
+                        // receiver is at least of the type of the method holder for a special
+                        // invoke.
+                        newReceiver = graph.unique(new PiNode(newReceiver, stamp));
+                    }
+                }
+
+                if (!StampTool.isPointerNonNull(newReceiver)) {
+                    LogicNode condition = graph.unique(IsNullNode.create(newReceiver));
+                    FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, NullCheckException, InvalidateReprofile, true));
+                    PiNode nonNullReceiver = graph.unique(new PiNode(newReceiver, StampFactory.objectNonNull(), fixedGuard));
+                    graph.addBeforeFixed(invoke.asNode(), fixedGuard);
+                    newReceiver = nonNullReceiver;
                 }
             }
 
-            if (!StampTool.isPointerNonNull(newReceiver)) {
-                LogicNode condition = graph.unique(IsNullNode.create(newReceiver));
-                FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, NullCheckException, InvalidateReprofile, true));
-                PiNode nonNullReceiver = graph.unique(new PiNode(newReceiver, StampFactory.objectNonNull(), fixedGuard));
-                graph.addBeforeFixed(invoke.asNode(), fixedGuard);
-                newReceiver = nonNullReceiver;
+            if (newReceiver != oldReceiver) {
+                callTarget.replaceFirstInput(oldReceiver, newReceiver);
             }
+            return newReceiver;
         }
-
-        if (newReceiver != oldReceiver) {
-            callTarget.replaceFirstInput(oldReceiver, newReceiver);
-        }
-        return newReceiver;
     }
 
     public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target, int invokeBci) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AbstractInlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AbstractInlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.common.inlining.info;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -54,10 +54,10 @@
     }
 
     @SuppressWarnings("try")
-    protected static EconomicSet<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, boolean receiverNullCheck) {
+    protected static EconomicSet<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, boolean receiverNullCheck, String reason) {
         assert inlineable instanceof InlineableGraph;
         StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
-        return InliningUtil.inlineForCanonicalization(invoke, calleeGraph, receiverNullCheck, concrete);
+        return InliningUtil.inlineForCanonicalization(invoke, calleeGraph, receiverNullCheck, concrete, reason, "InliningPhase");
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AssumptionInlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/AssumptionInlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.common.inlining.info;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
 import org.graalvm.compiler.nodes.Invoke;
@@ -46,9 +46,9 @@
     }
 
     @Override
-    public EconomicSet<Node> inline(Providers providers) {
+    public EconomicSet<Node> inline(Providers providers, String reason) {
         takenAssumption.recordTo(invoke.asNode().graph().getAssumptions());
-        return super.inline(providers);
+        return super.inline(providers, reason);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/ExactInlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/ExactInlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.common.inlining.info;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.phases.common.inlining.info.elem.Inlineable;
@@ -51,8 +51,8 @@
     }
 
     @Override
-    public EconomicSet<Node> inline(Providers providers) {
-        return inline(invoke, concrete, inlineableElement, !suppressNullCheck);
+    public EconomicSet<Node> inline(Providers providers, String reason) {
+        return inline(invoke, concrete, inlineableElement, !suppressNullCheck, reason);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/InlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/InlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.common.inlining.info;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -75,7 +75,7 @@
      *
      * @return a collection of nodes that need to be canonicalized after the inlining
      */
-    EconomicSet<Node> inline(Providers providers);
+    EconomicSet<Node> inline(Providers providers, String reason);
 
     /**
      * Try to make the call static bindable to avoid interface and virtual method calls.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -156,11 +156,11 @@
     }
 
     @Override
-    public EconomicSet<Node> inline(Providers providers) {
+    public EconomicSet<Node> inline(Providers providers, String reason) {
         if (hasSingleMethod()) {
-            return inlineSingleMethod(graph(), providers.getStampProvider(), providers.getConstantReflection());
+            return inlineSingleMethod(graph(), providers.getStampProvider(), providers.getConstantReflection(), reason);
         } else {
-            return inlineMultipleMethods(graph(), providers);
+            return inlineMultipleMethods(graph(), providers, reason);
         }
     }
 
@@ -182,7 +182,7 @@
         return notRecordedTypeProbability > 0;
     }
 
-    private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
+    private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers, String reason) {
         int numberOfMethods = concretes.size();
         FixedNode continuation = invoke.next();
 
@@ -277,7 +277,7 @@
         // do the actual inlining for every invoke
         for (int i = 0; i < numberOfMethods; i++) {
             Invoke invokeForInlining = (Invoke) successors[i].next();
-            canonicalizeNodes.addAll(doInline(i, invokeForInlining));
+            canonicalizeNodes.addAll(doInline(i, invokeForInlining, reason));
         }
         if (returnValuePhi != null) {
             canonicalizeNodes.add(returnValuePhi);
@@ -285,8 +285,8 @@
         return canonicalizeNodes;
     }
 
-    protected EconomicSet<Node> doInline(int index, Invoke invokeForInlining) {
-        return inline(invokeForInlining, methodAt(index), inlineableElementAt(index), false);
+    protected EconomicSet<Node> doInline(int index, Invoke invokeForInlining, String reason) {
+        return inline(invokeForInlining, methodAt(index), inlineableElementAt(index), false, reason);
     }
 
     private int getTypeCount(int concreteMethodIndex) {
@@ -322,7 +322,7 @@
         return result;
     }
 
-    private EconomicSet<Node> inlineSingleMethod(StructuredGraph graph, StampProvider stampProvider, ConstantReflectionProvider constantReflection) {
+    private EconomicSet<Node> inlineSingleMethod(StructuredGraph graph, StampProvider stampProvider, ConstantReflectionProvider constantReflection, String reason) {
         assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
         AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
@@ -333,7 +333,7 @@
 
         calleeEntryNode.setNext(invoke.asNode());
 
-        return inline(invoke, methodAt(0), inlineableElementAt(0), false);
+        return inline(invoke, methodAt(0), inlineableElementAt(0), false, reason);
     }
 
     private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, StampProvider stampProvider,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,8 +22,9 @@
  */
 package org.graalvm.compiler.phases.common.inlining.info;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
 import org.graalvm.compiler.nodes.ConstantNode;
@@ -98,9 +99,9 @@
     }
 
     @Override
-    public EconomicSet<Node> inline(Providers providers) {
+    public EconomicSet<Node> inline(Providers providers, String reason) {
         createGuard(graph(), providers);
-        return inline(invoke, concrete, inlineableElement, false);
+        return inline(invoke, concrete, inlineableElement, false, reason);
     }
 
     @Override
@@ -109,19 +110,22 @@
         InliningUtil.replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete);
     }
 
+    @SuppressWarnings("try")
     private void createGuard(StructuredGraph graph, Providers providers) {
-        ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
-        LoadHubNode receiverHub = graph.unique(new LoadHubNode(providers.getStampProvider(), nonNullReceiver));
-        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(NodeView.DEFAULT), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
+        try (DebugCloseable context = invoke.asNode().withNodeSourcePosition()) {
+            ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
+            LoadHubNode receiverHub = graph.unique(new LoadHubNode(providers.getStampProvider(), nonNullReceiver));
+            ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(NodeView.DEFAULT), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
 
-        LogicNode typeCheck = CompareNode.createCompareNode(graph, CanonicalCondition.EQ, receiverHub, typeHub, providers.getConstantReflection(), NodeView.DEFAULT);
-        FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
-        assert invoke.predecessor() != null;
+            LogicNode typeCheck = CompareNode.createCompareNode(graph, CanonicalCondition.EQ, receiverHub, typeHub, providers.getConstantReflection(), NodeView.DEFAULT);
+            FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
+            assert invoke.predecessor() != null;
 
-        ValueNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, guard, type, nonNullReceiver, true);
-        invoke.callTarget().replaceFirstInput(nonNullReceiver, anchoredReceiver);
+            ValueNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, guard, type, nonNullReceiver, true);
+            invoke.callTarget().replaceFirstInput(nonNullReceiver, anchoredReceiver);
 
-        graph.addBeforeFixed(invoke.asNode(), guard);
+            graph.addBeforeFixed(invoke.asNode(), guard);
+        }
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,6 +27,7 @@
 import static org.graalvm.compiler.core.common.GraalOptions.MaximumDesiredSize;
 import static org.graalvm.compiler.core.common.GraalOptions.MaximumInliningSize;
 import static org.graalvm.compiler.core.common.GraalOptions.SmallCompiledLowLevelGraphSize;
+import static org.graalvm.compiler.core.common.GraalOptions.TraceInlining;
 import static org.graalvm.compiler.core.common.GraalOptions.TrivialInliningSize;
 
 import java.util.Map;
@@ -61,8 +62,8 @@
     }
 
     @Override
-    public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
-
+    public Decision isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+        final boolean isTracing = TraceInlining.getValue(replacements.getOptions());
         final InlineInfo info = invocation.callee();
         OptionValues options = info.graph().getOptions();
         final double probability = invocation.probability();
@@ -70,17 +71,17 @@
 
         if (InlineEverything.getValue(options)) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "inline everything");
         }
 
         if (isIntrinsic(replacements, info)) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "intrinsic");
         }
 
         if (info.shouldInline()) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "forced inlining");
         }
 
         double inliningBonus = getInliningBonus(info);
@@ -90,12 +91,13 @@
         if (SmallCompiledLowLevelGraphSize.getValue(options) > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue(options) * inliningBonus) {
             InliningUtil.traceNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize,
                             relevance, probability, inliningBonus, nodes);
-            return false;
+            return InliningPolicy.Decision.NO.withReason(isTracing, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize,
+                            relevance, probability, inliningBonus, nodes);
         }
 
         if (nodes < TrivialInliningSize.getValue(options) * inliningBonus) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
         }
 
         /*
@@ -108,17 +110,19 @@
         if (LimitInlinedInvokes.getValue(options) > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue(options) * inliningBonus) {
             InliningUtil.traceNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance,
                             probability, inliningBonus, nodes);
-            return false;
+            return InliningPolicy.Decision.NO.withReason(isTracing, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance,
+                            probability, inliningBonus, nodes);
         }
 
         double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue(options) * inliningBonus));
         if (nodes <= maximumNodes) {
             InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
                             nodes, maximumNodes);
-            return true;
+            return InliningPolicy.Decision.YES.withReason(isTracing, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
+                            nodes, maximumNodes);
         }
 
         InliningUtil.traceNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
-        return false;
+        return InliningPolicy.Decision.NO.withReason(isTracing, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,6 +24,7 @@
 
 import static org.graalvm.compiler.core.common.GraalOptions.MaximumDesiredSize;
 
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.spi.Replacements;
@@ -41,7 +42,7 @@
     }
 
     @Override
-    public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
-        return true;
+    public Decision isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+        return Decision.YES.withReason(GraalOptions.TraceInlining.getValue(replacements.getOptions()), "inline everything");
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.phases.common.inlining.policy;
 
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.nodes.CallTargetNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.spi.Replacements;
@@ -35,14 +36,15 @@
 public final class InlineMethodSubstitutionsPolicy extends InlineEverythingPolicy {
 
     @Override
-    public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+    public Decision isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+        final boolean isTracing = GraalOptions.TraceInlining.getValue(replacements.getOptions());
         CallTargetNode callTarget = invocation.callee().invoke().callTarget();
         if (callTarget instanceof MethodCallTargetNode) {
             ResolvedJavaMethod calleeMethod = ((MethodCallTargetNode) callTarget).targetMethod();
             if (replacements.hasSubstitution(calleeMethod, invocation.callee().invoke().bci())) {
-                return true;
+                return Decision.YES.withReason(isTracing, "has a method subtitution");
             }
         }
-        return false;
+        return Decision.NO.withReason(isTracing, "does not have a method substitution");
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,36 @@
 import org.graalvm.compiler.phases.common.inlining.walker.MethodInvocation;
 
 public interface InliningPolicy {
+    class Decision {
+        public static final Decision YES = new Decision(true, "(unknown reason)");
+        public static final Decision NO = new Decision(false, "(unknown reason)");
+
+        private final boolean shouldInline;
+        private final String reason;
+
+        private Decision(boolean shouldInline, String reason) {
+            this.shouldInline = shouldInline;
+            this.reason = reason;
+        }
+
+        public boolean shouldInline() {
+            return shouldInline;
+        }
+
+        public String getReason() {
+            return reason;
+        }
+
+        public Decision withReason(boolean isTracing, String newReason, Object... args) {
+            if (isTracing) {
+                return new Decision(shouldInline, String.format(newReason, args));
+            } else {
+                return this;
+            }
+        }
+    }
 
     boolean continueInlining(StructuredGraph graph);
 
-    boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed);
+    Decision isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/CallsiteHolderExplorable.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/CallsiteHolderExplorable.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.util.LinkedList;
 import java.util.function.ToDoubleFunction;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.ParameterNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/ComputeInliningRelevance.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/ComputeInliningRelevance.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.ArrayList;
 import java.util.function.ToDoubleFunction;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.SuppressFBWarnings;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeWorkList;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Tue Apr 24 09:04:57 2018 -0700
@@ -34,8 +34,8 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
@@ -167,6 +167,7 @@
             return true;
         } else {
             InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), method, failureMessage);
+            invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, failureMessage);
             return false;
         }
     }
@@ -258,12 +259,14 @@
         JavaTypeProfile typeProfile = ((MethodCallTargetNode) invoke.callTarget()).getProfile();
         if (typeProfile == null) {
             InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no type profile exists");
+            invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "no type profile exists");
             return null;
         }
 
         JavaTypeProfile.ProfiledType[] ptypes = typeProfile.getTypes();
         if (ptypes == null || ptypes.length <= 0) {
             InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types in profile");
+            invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "no types in profile");
             return null;
         }
         ResolvedJavaType contextType = invoke.getContextType();
@@ -273,6 +276,7 @@
         if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
             if (!optimisticOpts.inlineMonomorphicCalls(options)) {
                 InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
+                invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "inlining monomorphic calls is disabled");
                 return null;
             }
 
@@ -288,6 +292,7 @@
 
             if (!optimisticOpts.inlinePolymorphicCalls(options) && notRecordedTypeProbability == 0) {
                 InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
+                invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
                 return null;
             }
             if (!optimisticOpts.inlineMegamorphicCalls(options) && notRecordedTypeProbability > 0) {
@@ -295,6 +300,8 @@
                 // the number of types is lower than what can be recorded in a type profile
                 InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
                                 notRecordedTypeProbability * 100);
+                invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null,
+                                "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, notRecordedTypeProbability);
                 return null;
             }
 
@@ -305,6 +312,7 @@
                 ResolvedJavaMethod concrete = ptypes[i].getType().resolveConcreteMethod(targetMethod, contextType);
                 if (concrete == null) {
                     InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "could not resolve method");
+                    invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "could not resolve method");
                     return null;
                 }
                 int index = concreteMethods.indexOf(concrete);
@@ -333,6 +341,8 @@
                     // No method left that is worth inlining.
                     InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
                                     concreteMethods.size());
+                    invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null,
+                                    "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size());
                     return null;
                 }
 
@@ -342,6 +352,7 @@
 
             if (concreteMethods.size() > maxMethodPerInlining) {
                 InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxMethodPerInlining);
+                invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "polymorphic call with more than %d target methods", maxMethodPerInlining);
                 return null;
             }
 
@@ -363,12 +374,16 @@
             if (usedTypes.isEmpty()) {
                 // No type left that is worth checking for.
                 InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
+                invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null, "no types remaining after filtering less frequent types (%d types previously)",
+                                ptypes.length);
                 return null;
             }
 
             for (ResolvedJavaMethod concrete : concreteMethods) {
                 if (!checkTargetConditions(invoke, concrete)) {
                     InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
+                    invoke.asNode().graph().getInliningLog().addDecision(invoke, false, "InliningPhase", null, null,
+                                    "it is a polymorphic method call and at least one invoked method cannot be inlined");
                     return null;
                 }
             }
@@ -393,14 +408,14 @@
     }
 
     @SuppressWarnings("try")
-    private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation) {
+    private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation, String reason) {
         StructuredGraph callerGraph = callerCallsiteHolder.graph();
         InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (DebugContext.Scope scope = debug.scope("doInline", callerGraph)) {
                 EconomicSet<Node> canonicalizedNodes = EconomicSet.create(Equivalence.IDENTITY);
                 canonicalizedNodes.addAll(calleeInfo.invoke().asNode().usages());
-                EconomicSet<Node> parameterUsages = calleeInfo.inline(new Providers(context));
+                EconomicSet<Node> parameterUsages = calleeInfo.inline(new Providers(context), reason);
                 canonicalizedNodes.addAll(parameterUsages);
                 counterInliningRuns.increment(debug);
                 debug.dump(DebugContext.DETAILED_LEVEL, callerGraph, "after %s", calleeInfo);
@@ -449,8 +464,9 @@
         assert callerCallsiteHolder.containsInvoke(calleeInfo.invoke());
         counterInliningConsidered.increment(debug);
 
-        if (inliningPolicy.isWorthInlining(context.getReplacements(), calleeInvocation, inliningDepth, true)) {
-            doInline(callerCallsiteHolder, calleeInvocation);
+        InliningPolicy.Decision decision = inliningPolicy.isWorthInlining(context.getReplacements(), calleeInvocation, inliningDepth, true);
+        if (decision.shouldInline()) {
+            doInline(callerCallsiteHolder, calleeInvocation, decision.getReason());
             return true;
         }
 
@@ -483,7 +499,7 @@
      * <p>
      * The {@link InlineInfo} used to get things rolling is kept around in the
      * {@link MethodInvocation}, it will be needed in case of inlining, see
-     * {@link InlineInfo#inline(Providers)}
+     * {@link InlineInfo#inline(Providers, String)}
      * </p>
      */
     private void processNextInvoke() {
@@ -709,7 +725,7 @@
 
         final MethodInvocation currentInvocation = currentInvocation();
 
-        final boolean backtrack = (!currentInvocation.isRoot() && !inliningPolicy.isWorthInlining(context.getReplacements(), currentInvocation, inliningDepth(), false));
+        final boolean backtrack = (!currentInvocation.isRoot() && !inliningPolicy.isWorthInlining(context.getReplacements(), currentInvocation, inliningDepth(), false).shouldInline());
         if (backtrack) {
             int remainingGraphs = currentInvocation.totalGraphs() - currentInvocation.processedGraphs();
             assert remainingGraphs > 0;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.graph.Graph.NodeEvent;
 import org.graalvm.compiler.graph.Graph.NodeEventListener;
 import org.graalvm.compiler.graph.Node;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/FixedNodeProbabilityCache.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/FixedNodeProbabilityCache.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 
 import java.util.function.ToDoubleFunction;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/PostOrderNodeIterator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/PostOrderNodeIterator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,8 @@
 import java.util.Deque;
 import java.util.Set;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeBitMap;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,8 +28,8 @@
 import java.util.List;
 import java.util.function.Predicate;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.RetryableBailoutException;
 import org.graalvm.compiler.core.common.cfg.Loop;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantNodeIterator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantNodeIterator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,9 +28,9 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractEndNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/SinglePassNodeIterator.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/SinglePassNodeIterator.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,8 @@
 import java.util.Deque;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeBitMap;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/MemoryScheduleVerification.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/MemoryScheduleVerification.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,8 +24,8 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.debug.DebugContext;
@@ -42,7 +42,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator;
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public final class MemoryScheduleVerification extends BlockIteratorClosure<EconomicSet<FloatingReadNode>> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.schedule;
 
-import static org.graalvm.collections.Equivalence.IDENTITY;
+import static jdk.internal.vm.compiler.collections.Equivalence.IDENTITY;
 import static org.graalvm.compiler.core.common.GraalOptions.GuardPriorities;
 import static org.graalvm.compiler.core.common.GraalOptions.OptScheduleOutOfLoops;
 import static org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.strictlyDominates;
@@ -38,7 +38,7 @@
 import java.util.TreeSet;
 import java.util.function.Function;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.SuppressFBWarnings;
 import org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
@@ -83,7 +83,7 @@
 import org.graalvm.compiler.nodes.spi.ValueProxy;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.Phase;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public final class SchedulePhase extends Phase {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,10 @@
  */
 package org.graalvm.compiler.phases.tiers;
 
+import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase;
+import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
+import org.graalvm.compiler.lir.phases.LIRPhase;
+import org.graalvm.compiler.lir.phases.LIRPhaseSuite;
 import org.graalvm.compiler.lir.phases.LIRSuites;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.PhaseSuite;
@@ -56,7 +60,25 @@
     }
 
     public static LIRSuites createLIRSuites(CompilerConfiguration config, OptionValues options) {
-        return new LIRSuites(config.createPreAllocationOptimizationStage(options), config.createAllocationStage(options), config.createPostAllocationOptimizationStage(options));
+        LIRPhaseSuite<AllocationContext> allocationStage = config.createAllocationStage(options);
+        assert verifyAllocationStage(allocationStage);
+        return new LIRSuites(config.createPreAllocationOptimizationStage(options), allocationStage, config.createPostAllocationOptimizationStage(options));
+    }
+
+    private static boolean verifyAllocationStage(LIRPhaseSuite<AllocationContext> allocationStage) {
+        boolean allocationPhase = false;
+        for (LIRPhase<?> phase : allocationStage.getPhases()) {
+            if (phase instanceof RegisterAllocationPhase) {
+                if (allocationPhase) {
+                    assert false : "More than one register allocation phase";
+                    return false;
+                }
+                allocationPhase = true;
+            }
+
+        }
+        assert allocationPhase : "No register allocation phase";
+        return allocationPhase;
     }
 
     public boolean isImmutable() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.GraalGraphError;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.phases.verify;
 
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import java.lang.annotation.Annotation;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,6 +26,9 @@
 import static org.graalvm.compiler.graph.Edges.Type.Successors;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -72,17 +75,26 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.Signature;
+import org.graalvm.graphio.GraphLocations;
 
 public class BinaryGraphPrinter implements
                 GraphStructure<BinaryGraphPrinter.GraphInfo, Node, NodeClass<?>, Edges>,
                 GraphBlocks<BinaryGraphPrinter.GraphInfo, Block, Node>,
                 GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition>,
+                GraphLocations<ResolvedJavaMethod, NodeSourcePosition, SourceLanguagePosition>,
                 GraphTypes, GraphPrinter {
     private final SnippetReflectionProvider snippetReflection;
     private final GraphOutput<BinaryGraphPrinter.GraphInfo, ResolvedJavaMethod> output;
 
     public BinaryGraphPrinter(DebugContext ctx, SnippetReflectionProvider snippetReflection) throws IOException {
-        this.output = ctx.buildOutput(GraphOutput.newBuilder(this).protocolVersion(5, 0).blocks(this).elements(this).types(this));
+        // @formatter:off
+        this.output = ctx.buildOutput(GraphOutput.newBuilder(this).
+                        protocolVersion(6, 0).
+                        blocks(this).
+                        elementsAndLocations(this, this).
+                        types(this)
+        );
+        // @formatter:on
         this.snippetReflection = snippetReflection;
     }
 
@@ -266,17 +278,6 @@
             }
             props.put("category", "floating");
         }
-        if (node.getNodeSourcePosition() != null) {
-            NodeSourcePosition pos = node.getNodeSourcePosition();
-            while (pos != null) {
-                SourceLanguagePosition cur = pos.getSourceLanauage();
-                if (cur != null) {
-                    cur.addSourceInformation(props);
-                    break;
-                }
-                pos = pos.getCaller();
-            }
-        }
         if (getSnippetReflectionProvider() != null) {
             for (Map.Entry<String, Object> prop : props.entrySet()) {
                 if (prop.getValue() instanceof JavaConstantFormattable) {
@@ -502,6 +503,85 @@
         return method.asStackTraceElement(bci);
     }
 
+    @Override
+    public Iterable<SourceLanguagePosition> methodLocation(ResolvedJavaMethod method, int bci, NodeSourcePosition pos) {
+        StackTraceElement e = methodStackTraceElement(method, bci, pos);
+        class JavaSourcePosition implements SourceLanguagePosition {
+
+            @Override
+            public String toShortString() {
+                return e.toString();
+            }
+
+            @Override
+            public int getOffsetEnd() {
+                return -1;
+            }
+
+            @Override
+            public int getOffsetStart() {
+                return -1;
+            }
+
+            @Override
+            public int getLineNumber() {
+                return e.getLineNumber();
+            }
+
+            @Override
+            public URI getURI() {
+                String path = e.getFileName();
+                try {
+                    return path == null ? null : new URI(null, null, path, null);
+                } catch (URISyntaxException ex) {
+                    throw new IllegalArgumentException(ex);
+                }
+            }
+
+            @Override
+            public String getLanguage() {
+                return "Java";
+            }
+        }
+
+        List<SourceLanguagePosition> arr = new ArrayList<>();
+        arr.add(new JavaSourcePosition());
+        NodeSourcePosition at = pos;
+        while (at != null) {
+            SourceLanguagePosition cur = at.getSourceLanguage();
+            if (cur != null) {
+                arr.add(cur);
+            }
+            at = at.getCaller();
+        }
+        return arr;
+    }
+
+    @Override
+    public String locationLanguage(SourceLanguagePosition location) {
+        return location.getLanguage();
+    }
+
+    @Override
+    public URI locationURI(SourceLanguagePosition location) {
+        return location.getURI();
+    }
+
+    @Override
+    public int locationLineNumber(SourceLanguagePosition location) {
+        return location.getLineNumber();
+    }
+
+    @Override
+    public int locationOffsetStart(SourceLanguagePosition location) {
+        return location.getOffsetStart();
+    }
+
+    @Override
+    public int locationOffsetEnd(SourceLanguagePosition location) {
+        return location.getOffsetEnd();
+    }
+
     static final class GraphInfo {
         final DebugContext debug;
         final Graph graph;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinter.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinter.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,7 +33,7 @@
 import java.util.Map;
 import java.util.TreeMap;
 
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
 import org.graalvm.compiler.core.common.alloc.Trace;
@@ -116,38 +116,38 @@
     }
 
     private void printBlock(BciBlockMapping.BciBlock block) {
-        out.print("name \"B").print(block.startBci).println('"');
-        out.print("from_bci ").println(block.startBci);
-        out.print("to_bci ").println(block.endBci);
+        out.print("name \"B").print(block.getStartBci()).println('"');
+        out.print("from_bci ").println(block.getStartBci());
+        out.print("to_bci ").println(block.getEndBci());
 
         out.println("predecessors ");
 
         out.print("successors ");
         for (BciBlockMapping.BciBlock succ : block.getSuccessors()) {
-            if (!succ.isExceptionEntry) {
-                out.print("\"B").print(succ.startBci).print("\" ");
+            if (!succ.isExceptionEntry()) {
+                out.print("\"B").print(succ.getStartBci()).print("\" ");
             }
         }
         out.println();
 
         out.print("xhandlers");
         for (BciBlockMapping.BciBlock succ : block.getSuccessors()) {
-            if (succ.isExceptionEntry) {
-                out.print("\"B").print(succ.startBci).print("\" ");
+            if (succ.isExceptionEntry()) {
+                out.print("\"B").print(succ.getStartBci()).print("\" ");
             }
         }
         out.println();
 
         out.print("flags ");
-        if (block.isExceptionEntry) {
+        if (block.isExceptionEntry()) {
             out.print("\"ex\" ");
         }
-        if (block.isLoopHeader) {
+        if (block.isLoopHeader()) {
             out.print("\"plh\" ");
         }
         out.println();
 
-        out.print("loop_depth ").println(Long.bitCount(block.loops));
+        out.print("loop_depth ").println(Long.bitCount(block.getLoops()));
     }
 
     private NodeMap<Block> latestScheduling;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,15 +37,13 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.util.JavaConstantFormatter;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.MetaUtil;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.runtime.JVMCI;
-import jdk.vm.ci.services.Services;
 
 interface GraphPrinter extends Closeable, JavaConstantFormatter {
 
@@ -72,16 +70,6 @@
     void close();
 
     /**
-     * A JVMCI package dynamically exported to trusted modules.
-     */
-    String JVMCI_RUNTIME_PACKAGE = JVMCI.class.getPackage().getName();
-
-    /**
-     * {@code jdk.vm.ci} module.
-     */
-    Object JVMCI_MODULE = JDK9Method.JAVA_SPECIFICATION_VERSION < 9 ? null : JDK9Method.getModule(Services.class);
-
-    /**
      * Classes whose {@link #toString()} method does not run any untrusted code.
      */
     List<Class<?>> TRUSTED_CLASSES = Arrays.asList(
@@ -105,17 +93,8 @@
         if (TRUSTED_CLASSES.contains(c)) {
             return true;
         }
-        if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
-            if (c.getClassLoader() == Services.class.getClassLoader()) {
-                // Loaded by the JVMCI class loader
-                return true;
-            }
-        } else {
-            Object module = JDK9Method.getModule(c);
-            if (JVMCI_MODULE == module || JDK9Method.isOpenTo(JVMCI_MODULE, JVMCI_RUNTIME_PACKAGE, module)) {
-                // Can access non-statically-exported package in JVMCI
-                return true;
-            }
+        if (GraalServices.isToStringTrusted(c)) {
+            return true;
         }
         if (c.getClassLoader() == GraphPrinter.class.getClassLoader()) {
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Tue Apr 24 09:04:57 2018 -0700
@@ -45,6 +45,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.contract.NodeCostUtil;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.meta.JavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -86,11 +87,11 @@
     }
 
     private static String jvmArguments() {
-        try {
-            return String.join(" ", java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments());
-        } catch (LinkageError err) {
-            return "unknown";
+        List<String> inputArguments = GraalServices.getInputArguments();
+        if (inputArguments != null) {
+            return String.join(" ", inputArguments);
         }
+        return "unknown";
     }
 
     private void ensureInitialized(DebugContext ctx, Graph graph) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,6 +28,7 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
+import static org.graalvm.compiler.serviceprovider.GraalServices.JAVA_SPECIFICATION_VERSION;
 
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -53,6 +54,9 @@
                 registerIntegerLongPlugins(invocationPlugins, AArch64IntegerSubstitutions.class, JavaKind.Int, bytecodeProvider);
                 registerIntegerLongPlugins(invocationPlugins, AArch64LongSubstitutions.class, JavaKind.Long, bytecodeProvider);
                 registerMathPlugins(invocationPlugins);
+                registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
+                registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
+
             }
         });
     }
@@ -114,4 +118,23 @@
             }
         });
     }
+
+    private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+        if (JAVA_SPECIFICATION_VERSION >= 9) {
+            Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
+            r.setAllowOverwrite(true);
+            r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
+            r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
+        }
+    }
+
+    private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+        if (JAVA_SPECIFICATION_VERSION >= 9) {
+            Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
+            r.setAllowOverwrite(true);
+            r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
+            r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
+        }
+    }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.graalvm.compiler.replacements.aarch64;
-
-import jdk.vm.ci.aarch64.AArch64Kind;
-import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator;
-import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator;
-import org.graalvm.compiler.core.common.type.IntegerStamp;
-import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.FrameState;
-import org.graalvm.compiler.nodes.NodeView;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.calc.SignExtendNode;
-import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
-import org.graalvm.compiler.nodes.extended.GuardingNode;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
-
-/**
- * AArch64-specific subclass of ReadNode that knows how to merge ZeroExtend and SignExtend into the
- * read.
- */
-
-@NodeInfo
-public class AArch64ReadNode extends ReadNode {
-    public static final NodeClass<AArch64ReadNode> TYPE = NodeClass.create(AArch64ReadNode.class);
-    private final IntegerStamp accessStamp;
-    private final boolean isSigned;
-
-    public AArch64ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck,
-                    FrameState stateBefore, IntegerStamp accessStamp, boolean isSigned) {
-        super(TYPE, address, location, stamp, guard, barrierType, nullCheck, stateBefore);
-        this.accessStamp = accessStamp;
-        this.isSigned = isSigned;
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool gen) {
-        AArch64LIRGenerator lirgen = (AArch64LIRGenerator) gen.getLIRGeneratorTool();
-        AArch64ArithmeticLIRGenerator arithgen = (AArch64ArithmeticLIRGenerator) lirgen.getArithmetic();
-        AArch64Kind readKind = (AArch64Kind) lirgen.getLIRKind(accessStamp).getPlatformKind();
-        int resultBits = ((IntegerStamp) stamp(NodeView.DEFAULT)).getBits();
-        gen.setResult(this, arithgen.emitExtendMemory(isSigned, readKind, resultBits, (AArch64AddressValue) gen.operand(getAddress()), gen.state(this)));
-    }
-
-    /**
-     * replace a ReadNode with an AArch64-specific variant which knows how to merge a downstream
-     * zero or sign extend into the read operation.
-     *
-     * @param readNode
-     */
-    public static void replace(ReadNode readNode) {
-        assert readNode.getUsageCount() == 1;
-        assert readNode.getUsageAt(0) instanceof ZeroExtendNode || readNode.getUsageAt(0) instanceof SignExtendNode;
-
-        ValueNode usage = (ValueNode) readNode.getUsageAt(0);
-        boolean isSigned = usage instanceof SignExtendNode;
-        IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp());
-
-        AddressNode address = readNode.getAddress();
-        LocationIdentity location = readNode.getLocationIdentity();
-        Stamp stamp = usage.stamp(NodeView.DEFAULT);
-        GuardingNode guard = readNode.getGuard();
-        BarrierType barrierType = readNode.getBarrierType();
-        boolean nullCheck = readNode.getNullCheck();
-        FrameState stateBefore = readNode.stateBefore();
-        AArch64ReadNode clone = new AArch64ReadNode(address, location, stamp, guard, barrierType, nullCheck, stateBefore, accessStamp, isSigned);
-        StructuredGraph graph = readNode.graph();
-        graph.add(clone);
-        // splice out the extend node
-        usage.replaceAtUsagesAndDelete(readNode);
-        // swap the clone for the read
-        graph.replaceFixedWithFixed(readNode, clone);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadReplacementPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.graalvm.compiler.replacements.aarch64;
-
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.calc.SignExtendNode;
-import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.phases.Phase;
-
-/**
- * AArch64-specific phase which substitutes certain read nodes with arch-specific variants in order
- * to allow merging of zero and sign extension into the read operation.
- */
-
-public class AArch64ReadReplacementPhase extends Phase {
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Node node : graph.getNodes()) {
-            // don't process nodes we just added
-            if (node instanceof AArch64ReadNode) {
-                continue;
-            }
-            if (node instanceof ReadNode) {
-                ReadNode readNode = (ReadNode) node;
-                if (readNode.getUsageCount() == 1) {
-                    Node usage = readNode.getUsageAt(0);
-                    if (usage instanceof ZeroExtendNode || usage instanceof SignExtendNode) {
-                        AArch64ReadNode.replace(readNode);
-                    }
-                }
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64StringLatin1Substitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.replacements.aarch64;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+
+import jdk.vm.ci.meta.JavaKind;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for {@code java.lang.StringLatin1} methods.
+ *
+ * Since JDK 9.
+ */
+@ClassSubstitution(className = "java.lang.StringLatin1", optional = true)
+public class AArch64StringLatin1Substitutions {
+
+    /**
+     * @param value is byte[]
+     * @param other is char[]
+     */
+    @MethodSubstitution
+    public static int compareTo(byte[] value, byte[] other) {
+        return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Byte);
+    }
+
+    /**
+     * @param value is byte[]
+     * @param other is char[]
+     */
+    @MethodSubstitution
+    public static int compareToUTF16(byte[] value, byte[] other) {
+        return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Char);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64StringUTF16Substitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.replacements.aarch64;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+
+import jdk.vm.ci.meta.JavaKind;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for {@code java.lang.StringUTF16} methods.
+ *
+ * Since JDK 9.
+ */
+@ClassSubstitution(className = "java.lang.StringUTF16", optional = true)
+public class AArch64StringUTF16Substitutions {
+
+    /**
+     * @param value is char[]
+     * @param other is char[]
+     */
+    @MethodSubstitution
+    public static int compareTo(byte[] value, byte[] other) {
+        return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Char, JavaKind.Char);
+    }
+
+    /**
+     * @param value is char[]
+     * @param other is byte[]
+     */
+    @MethodSubstitution
+    public static int compareToLatin1(byte[] value, byte[] other) {
+        /*
+         * Swapping array arguments because intrinsic expects order to be byte[]/char[] but kind
+         * arguments stay in original order.
+         */
+        return ArrayCompareToNode.compareTo(other, value, other.length, value.length, JavaKind.Char, JavaKind.Byte);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,8 +29,8 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.JAVA_SPECIFICATION_VERSION;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import java.util.Arrays;
 
@@ -57,7 +57,7 @@
 import org.graalvm.compiler.replacements.nodes.BitCountNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64.CPUFeature;
@@ -194,8 +194,7 @@
                 r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
                                 int.class, char[].class, int.class, int.class, int.class);
             }
-            // r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo",
-            // Receiver.class, String.class);
+            r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo", Receiver.class, String.class);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,8 +38,8 @@
 import org.graalvm.compiler.nodes.memory.MemoryNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,7 +32,7 @@
 import org.graalvm.compiler.replacements.StringSubstitutions;
 import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.Pointer;
+import jdk.internal.vm.compiler.word.Pointer;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/NestedExceptionHandlerTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/NestedExceptionHandlerTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,12 +22,20 @@
  */
 package org.graalvm.compiler.replacements.test;
 
+import static org.graalvm.compiler.core.common.GraalOptions.RemoveNeverExecutedCode;
+import static org.graalvm.compiler.core.common.GraalOptions.UseExceptionProbability;
+import static org.graalvm.compiler.core.common.GraalOptions.UseTypeCheckHints;
+
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionValues;
+import org.junit.Ignore;
 import org.junit.Test;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class NestedExceptionHandlerTest extends GraalCompilerTest {
 
     @BytecodeParserNeverInline(invokeWithException = true)
@@ -63,4 +71,67 @@
         test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "nestedExceptionHandler");
     }
 
+    @SuppressWarnings("try")
+    public static String snippet1() {
+        try {
+            synchronized (String.class) {
+                try (AutoCloseable scope = null) {
+                    return "RETURN";
+                } catch (Throwable t) {
+                    return t.toString();
+                }
+            }
+        } finally {
+            raise();
+        }
+    }
+
+    public static void raise() {
+        throw new RuntimeException();
+    }
+
+    @SuppressWarnings("try")
+    public static String snippet2() {
+        try {
+            synchronized (String.class) {
+                try (AutoCloseable scope = null) {
+                    return performCompilation();
+                } catch (Throwable t) {
+                    return t.toString();
+                }
+            }
+        } finally {
+            synchronized (String.class) {
+                String.class.toString();
+            }
+        }
+    }
+
+    private static String performCompilation() {
+        return "passed";
+    }
+
+    @Ignore("https://bugs.eclipse.org/bugs/show_bug.cgi?id=533187")
+    @Test
+    public void testSnippet1() {
+        OptionValues options = parseAllCodeWithoutInlining();
+        ResolvedJavaMethod method = getResolvedJavaMethod("snippet1");
+        parseEager(method, AllowAssumptions.YES, options);
+    }
+
+    @Ignore("https://bugs.eclipse.org/bugs/show_bug.cgi?id=533187")
+    @Test
+    public void testSnippet2() {
+        OptionValues options = parseAllCodeWithoutInlining();
+        ResolvedJavaMethod method = getResolvedJavaMethod("snippet2");
+        parseEager(method, AllowAssumptions.YES, options);
+    }
+
+    private static OptionValues parseAllCodeWithoutInlining() {
+        OptionValues options = new OptionValues(getInitialOptions(),
+                        UseTypeCheckHints, false,
+                        UseExceptionProbability, false,
+                        RemoveNeverExecutedCode, false);
+        return options;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -33,9 +33,9 @@
 import org.graalvm.compiler.nodes.extended.JavaWriteNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
 import org.graalvm.compiler.word.ObjectAccess;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -45,7 +45,7 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.replacements.CachingPEGraphDecoder;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,9 +37,9 @@
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordCastNode;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -62,7 +62,7 @@
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,10 +26,10 @@
 import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.aarch64.AArch64;
 import jdk.vm.ci.code.InstalledCode;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
@@ -49,6 +49,7 @@
                     "\uFF21\uFF21",
                     "\u043c\u0430\u043c\u0430\u0020\u043c\u044b\u043b\u0430\u0020\u0440\u0430\u043c\u0443\u002c\u0020\u0440\u0430\u043c\u0430\u0020\u0441\u044a\u0435\u043b\u0430\u0020\u043c\u0430\u043c\u0443",
                     "crazy dog jumps over laszy fox",
+                    "some-string\0xff",
                     "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-",
                     "XMM-XMM+YMM-YMM-ZMM-ZMM-ZMM-ZMM-",
                     "XMM-XMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-",
@@ -61,7 +62,7 @@
     };
 
     public StringCompareToTest() {
-        Assume.assumeTrue(getTarget().arch instanceof AMD64);
+        Assume.assumeTrue((getTarget().arch instanceof AMD64) || (getTarget().arch instanceof AArch64));
 
         realMethod = getResolvedJavaMethod(String.class, "compareTo", String.class);
         testMethod = getResolvedJavaMethod("stringCompareTo");
@@ -91,24 +92,35 @@
     }
 
     @Test
-    @Ignore("GR-8748")
     public void testEqualString() {
         String s = "equal-string";
         executeStringCompareTo(s, new String(s.toCharArray()));
     }
 
     @Test
-    @Ignore("GR-8748")
     public void testDifferentString() {
-        executeStringCompareTo("some-string", "different-string");
+        // Smoke test for primary cases
+        executeStringCompareTo("AAAAAAAA", "");
+        // LL
+        executeStringCompareTo("some-stringA", "some-string\0xff");
+        // UU
+        executeStringCompareTo("\u2241AAAAAAAB", "\u2241\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41");
+        // LU
+        executeStringCompareTo("AAAAAAAAB", "\u0041\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41");
     }
 
     @Test
-    @Ignore("GR-8748")
     public void testAllStrings() {
         for (String s0 : testData) {
             for (String s1 : testData) {
-                executeStringCompareTo(s0, s1);
+                try {
+                    executeStringCompareTo(s0, s1);
+                } catch (AssertionError ex) {
+                    System.out.println("FAIL: '" + ex + "'");
+                    System.out.println(" ***: s0 '" + s0 + "'");
+                    System.out.println(" ***: s1 '" + s1 + "'");
+                    throw ex;
+                }
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,10 +29,10 @@
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
 import org.junit.Test;
 
 /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -149,7 +149,7 @@
                     for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
                         final ZipEntry zipEntry = entry.nextElement();
                         String name = zipEntry.getName();
-                        if (name.endsWith(".class") && !name.equals("module-info.class")) {
+                        if (name.endsWith(".class") && !name.equals("module-info.class") && !name.startsWith("META-INF/versions/")) {
                             String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
                             if (isInNativeImage(className)) {
                                 /*
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING;
 
-import org.graalvm.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.SourceLanguagePositionProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -48,6 +48,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
@@ -131,7 +132,7 @@
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.MemoryBarriers;
@@ -526,7 +527,8 @@
         ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue());
 
         AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset()));
-        LogicCompareAndSwapNode atomicNode = graph.add(new LogicCompareAndSwapNode(address, cas.getLocationIdentity(), expectedValue, newValue, compareAndSwapBarrierType(cas)));
+        BarrierType barrierType = storeBarrierType(cas.object(), expectedValue);
+        LogicCompareAndSwapNode atomicNode = graph.add(new LogicCompareAndSwapNode(address, cas.getLocationIdentity(), expectedValue, newValue, barrierType));
         atomicNode.setStateAfter(cas.stateAfter());
         graph.replaceFixedWithFixed(cas, atomicNode);
     }
@@ -538,7 +540,8 @@
         ValueNode newValue = implicitStoreConvert(graph, valueKind, n.newValue());
 
         AddressNode address = graph.unique(new OffsetAddressNode(n.object(), n.offset()));
-        LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(address, n.getLocationIdentity(), newValue, atomicReadAndWriteBarrierType(n)));
+        BarrierType barrierType = storeBarrierType(n.object(), n.newValue());
+        LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(address, n.getLocationIdentity(), newValue, barrierType));
         memoryRead.setStateAfter(n.stateAfter());
 
         ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead);
@@ -673,6 +676,7 @@
         memoryWrite.setGuard(write.getGuard());
     }
 
+    @SuppressWarnings("try")
     protected void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTool tool) {
         StructuredGraph graph = commit.graph();
         if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
@@ -685,10 +689,12 @@
                 VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
                 int entryCount = virtual.entryCount();
                 AbstractNewObjectNode newObject;
-                if (virtual instanceof VirtualInstanceNode) {
-                    newObject = graph.add(createNewInstanceFromVirtual(virtual));
-                } else {
-                    newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
+                try (DebugCloseable nsp = virtual.withNodeSourcePosition()) {
+                    if (virtual instanceof VirtualInstanceNode) {
+                        newObject = graph.add(createNewInstanceFromVirtual(virtual));
+                    } else {
+                        newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
+                    }
                 }
                 recursiveLowerings.add(newObject);
                 graph.addBeforeFixed(commit, newObject);
@@ -884,23 +890,15 @@
         return entryKind == JavaKind.Object ? BarrierType.PRECISE : BarrierType.NONE;
     }
 
-    protected BarrierType unsafeStoreBarrierType(RawStoreNode store) {
+    private static BarrierType unsafeStoreBarrierType(RawStoreNode store) {
         if (!store.needsBarrier()) {
             return BarrierType.NONE;
         }
         return storeBarrierType(store.object(), store.value());
     }
 
-    protected BarrierType compareAndSwapBarrierType(UnsafeCompareAndSwapNode cas) {
-        return storeBarrierType(cas.object(), cas.expected());
-    }
-
-    protected BarrierType atomicReadAndWriteBarrierType(AtomicReadAndWriteNode n) {
-        return storeBarrierType(n.object(), n.newValue());
-    }
-
-    protected BarrierType storeBarrierType(ValueNode object, ValueNode value) {
-        if (value.getStackKind() == JavaKind.Object) {
+    private static BarrierType storeBarrierType(ValueNode object, ValueNode value) {
+        if (value.getStackKind() == JavaKind.Object && object.getStackKind() == JavaKind.Object) {
             ResolvedJavaType type = StampTool.typeOrNull(object);
             if (type != null && !type.isArray()) {
                 return BarrierType.IMPRECISE;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,10 +29,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
 import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node.ValueNumberable;
@@ -71,7 +73,7 @@
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -99,9 +101,20 @@
     protected abstract static class Structure {
     }
 
-    public GraphKit(StructuredGraph graph, Providers providers, WordTypes wordTypes, GraphBuilderConfiguration.Plugins graphBuilderPlugins) {
+    public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, Plugins graphBuilderPlugins, CompilationIdentifier compilationId, String name) {
         this.providers = providers;
-        this.graph = graph;
+        StructuredGraph.Builder builder = new StructuredGraph.Builder(debug.getOptions(), debug).compilationId(compilationId);
+        if (name != null) {
+            builder.name(name);
+        } else {
+            builder.method(stubMethod);
+        }
+        this.graph = builder.build();
+        graph.disableUnsafeAccessTracking();
+        if (graph.trackNodeSourcePosition()) {
+            // Set up a default value that everything constructed by GraphKit will use.
+            graph.withNodeSourcePosition(NodeSourcePosition.substitution(stubMethod));
+        }
         this.wordTypes = wordTypes;
         this.graphBuilderPlugins = graphBuilderPlugins;
         this.lastFixedNode = graph.start();
@@ -229,7 +242,7 @@
      */
     @SuppressWarnings("try")
     public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
-        try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.placeholder(method))) {
+        try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
             assert method.isStatic() == (invokeKind == InvokeKind.Static);
             Signature signature = method.getSignature();
             JavaType returnType = signature.getReturnType(null);
@@ -254,15 +267,29 @@
         }
     }
 
+    @SuppressWarnings("try")
     public InvokeWithExceptionNode createInvokeWithExceptionAndUnwind(ResolvedJavaMethod method, InvokeKind invokeKind,
                     FrameStateBuilder frameStateBuilder, int invokeBci, int exceptionEdgeBci, ValueNode... args) {
+        try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
+            InvokeWithExceptionNode result = startInvokeWithException(method, invokeKind, frameStateBuilder, invokeBci, exceptionEdgeBci, args);
+            exceptionPart();
+            ExceptionObjectNode exception = exceptionObject();
+            append(new UnwindNode(exception));
+            endInvokeWithException();
+            return result;
+        }
+    }
 
-        InvokeWithExceptionNode result = startInvokeWithException(method, invokeKind, frameStateBuilder, invokeBci, exceptionEdgeBci, args);
-        exceptionPart();
-        ExceptionObjectNode exception = exceptionObject();
-        append(new UnwindNode(exception));
-        endInvokeWithException();
-        return result;
+    @SuppressWarnings("try")
+    public InvokeWithExceptionNode createInvokeWithExceptionAndUnwind(MethodCallTargetNode callTarget, FrameStateBuilder frameStateBuilder, int invokeBci, int exceptionEdgeBci) {
+        try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), callTarget.targetMethod()))) {
+            InvokeWithExceptionNode result = startInvokeWithException(callTarget, frameStateBuilder, invokeBci, exceptionEdgeBci);
+            exceptionPart();
+            ExceptionObjectNode exception = exceptionObject();
+            append(new UnwindNode(exception));
+            endInvokeWithException();
+            return result;
+        }
     }
 
     protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, @SuppressWarnings("unused") int bci) {
@@ -305,10 +332,10 @@
     /**
      * Recursively {@linkplain #inline inlines} all invocations currently in the graph.
      */
-    public void inlineInvokes() {
+    public void inlineInvokes(String reason, String phase) {
         while (!graph.getNodes().filter(InvokeNode.class).isEmpty()) {
             for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) {
-                inline(invoke);
+                inline(invoke, reason, phase);
             }
         }
 
@@ -320,7 +347,7 @@
      * Inlines a given invocation to a method. The graph of the inlined method is processed in the
      * same manner as for snippets and method substitutions.
      */
-    public void inline(InvokeNode invoke) {
+    public void inline(InvokeNode invoke, String reason, String phase) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
 
         MetaAccessProvider metaAccess = providers.getMetaAccess();
@@ -341,7 +368,7 @@
         calleeGraph.clearAllStateAfter();
         new DeadCodeEliminationPhase(Optionality.Required).apply(calleeGraph);
 
-        InliningUtil.inline(invoke, calleeGraph, false, method);
+        InliningUtil.inline(invoke, calleeGraph, false, method, reason, phase);
     }
 
     protected void pushStructure(Structure structure) {
@@ -493,6 +520,11 @@
         if (returnStamp == null) {
             returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
         }
+        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, invokeBci));
+        return startInvokeWithException(callTarget, frameStateBuilder, invokeBci, exceptionEdgeBci);
+    }
+
+    public InvokeWithExceptionNode startInvokeWithException(MethodCallTargetNode callTarget, FrameStateBuilder frameStateBuilder, int invokeBci, int exceptionEdgeBci) {
         ExceptionObjectNode exceptionObject = add(new ExceptionObjectNode(getMetaAccess()));
         if (frameStateBuilder != null) {
             FrameStateBuilder exceptionState = frameStateBuilder.copy();
@@ -501,7 +533,6 @@
             exceptionState.setRethrowException(false);
             exceptionObject.setStateAfter(exceptionState.create(exceptionEdgeBci, exceptionObject));
         }
-        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, invokeBci));
         InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionObject, invokeBci));
         AbstractBeginNode noExceptionEdge = graph.add(KillingBeginNode.create(LocationIdentity.any()));
         invoke.setNext(noExceptionEdge);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.replacements;
 
+import static org.graalvm.compiler.core.common.GraalOptions.MaximumRecursiveInlining;
+
 import org.graalvm.compiler.core.common.type.StampPair;
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.CallTargetNode;
@@ -46,6 +48,16 @@
         this.safeForDeoptimization = safeForDeoptimization;
     }
 
+    private static int countRecursiveInlining(GraphBuilderContext b, ResolvedJavaMethod method) {
+        int count = 0;
+        for (GraphBuilderContext c = b.getParent(); c != null; c = c.getParent()) {
+            if (method.equals(c.getMethod())) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     @Override
     public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
         IntrinsicMethod intrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(method);
@@ -83,11 +95,19 @@
                     // As such, it needs to recursively inline everything.
                     inlineEverything = args.length != argumentsList.size();
                 }
-                if (inlineEverything && !callTarget.targetMethod().hasBytecodes()) {
+                ResolvedJavaMethod targetMethod = callTarget.targetMethod();
+                if (inlineEverything && !targetMethod.hasBytecodes()) {
                     // we need to force-inline but we can not, leave the invoke as-is
                     return false;
                 }
-                b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), argumentsList.toArray(new ValueNode[argumentsList.size()]), inlineEverything);
+
+                int recursionDepth = countRecursiveInlining(b, targetMethod);
+                int maxRecursionDepth = MaximumRecursiveInlining.getValue(b.getOptions());
+                if (recursionDepth > maxRecursionDepth) {
+                    return false;
+                }
+
+                b.handleReplacedInvoke(invoke.getInvokeKind(), targetMethod, argumentsList.toArray(new ValueNode[argumentsList.size()]), inlineEverything);
             }
             return true;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Tue Apr 24 09:04:57 2018 -0700
@@ -32,8 +32,8 @@
 import java.util.List;
 import java.util.Map;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,8 +36,8 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.api.replacements.Fold;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
 import org.graalvm.compiler.api.replacements.Snippet;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -50,7 +50,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.word.ObjectAccess;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.TargetDescription;
 import sun.misc.Unsafe;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
 public class SnippetLowerableMemoryNode extends FixedWithNextNode implements Lowerable, MemoryAccess {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Tue Apr 24 09:04:57 2018 -0700
@@ -30,7 +30,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
@@ -47,10 +47,10 @@
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Predicate;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
 import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter;
@@ -131,8 +131,8 @@
 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
 import org.graalvm.compiler.replacements.nodes.LoadSnippetVarargParameterNode;
 import org.graalvm.util.CollectionsUtil;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordBase;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordBase;
 
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.Constant;
@@ -651,8 +651,9 @@
                 try (DebugContext debug = openDebugContext(outer, args)) {
                     try (DebugCloseable a = SnippetTemplateCreationTime.start(debug); DebugContext.Scope s = debug.scope("SnippetSpecialization", args.info.method)) {
                         SnippetTemplates.increment(debug);
-                        template = new SnippetTemplate(options, debug, providers, snippetReflection, args, graph.trackNodeSourcePosition(), replacee);
-                        if (Options.UseSnippetTemplateCache.getValue(options) && args.cacheable) {
+                        OptionValues snippetOptions = new OptionValues(options, GraalOptions.TraceInlining, GraalOptions.TraceInliningForStubsAndSnippets.getValue(options));
+                        template = new SnippetTemplate(snippetOptions, debug, providers, snippetReflection, args, graph.trackNodeSourcePosition(), replacee);
+                        if (Options.UseSnippetTemplateCache.getValue(snippetOptions) && args.cacheable) {
                             templates.put(args.cacheKey, template);
                         }
                     } catch (Throwable e) {
@@ -1516,9 +1517,7 @@
                 replaceeGraph.getInliningLog().addLog(duplicates, snippet.getInliningLog());
             }
             NodeSourcePosition position = replacee.getNodeSourcePosition();
-            if (position != null) {
-                InliningUtil.updateSourcePosition(replaceeGraph, duplicates, mark, position, true);
-            }
+            InliningUtil.updateSourcePosition(replaceeGraph, duplicates, mark, position, true);
             debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
             return duplicates;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Tue Apr 24 09:04:57 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
 import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
@@ -105,7 +105,7 @@
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactNode;
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactNode;
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
@@ -233,10 +233,10 @@
                 // Ordered object-based accesses
                 if (Java8OrEarlier) {
                     if (kind == JavaKind.Int || kind == JavaKind.Long || kind == JavaKind.Object) {
-                        r.register4("putOrdered" + kindName, Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, true));
+                        r.register4("putOrdered" + kindName, Receiver.class, Object.class, long.class, javaClass, UnsafePutPlugin.putOrdered(kind));
                     }
                 } else {
-                    r.register4("put" + kindName + "Release", Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, true));
+                    r.register4("put" + kindName + "Release", Receiver.class, Object.class, long.class, javaClass, UnsafePutPlugin.putOrdered(kind));
                 }
                 if (kind != JavaKind.Boolean && kind != JavaKind.Object) {
                     // Raw accesses to memory addresses
@@ -693,15 +693,29 @@
     public static class UnsafePutPlugin implements InvocationPlugin {
 
         private final JavaKind kind;
-        private final boolean isVolatile;
+        private final boolean hasBarrier;
+        private final int preWrite;
+        private final int postWrite;
 
         public UnsafePutPlugin(JavaKind kind, boolean isVolatile) {
+            this(kind, isVolatile, JMM_PRE_VOLATILE_WRITE, JMM_POST_VOLATILE_WRITE);
+        }
+
+        private UnsafePutPlugin(JavaKind kind, boolean hasBarrier, int preWrite, int postWrite) {
+            super();
             this.kind = kind;
-            this.isVolatile = isVolatile;
+            this.hasBarrier = hasBarrier;
+            this.preWrite = preWrite;
+            this.postWrite = postWrite;
+        }
+
+        public static UnsafePutPlugin putOrdered(JavaKind kind) {
+            return new UnsafePutPlugin(kind, true, LOAD_STORE | STORE_STORE, 0);
         }
 
         @Override
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address, ValueNode value) {
+            assert !hasBarrier : "Barriers for address based Unsafe put is not supported.";
             // Emits a null-check for the otherwise unused receiver
             unsafe.get();
             b.add(new UnsafeMemoryStoreNode(address, value, kind, OFF_HEAP_LOCATION));
@@ -713,13 +727,13 @@
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) {
             // Emits a null-check for the otherwise unused receiver
             unsafe.get();
-            if (isVolatile) {
-                b.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+            if (hasBarrier) {
+                b.add(new MembarNode(preWrite));
             }
             LocationIdentity locationIdentity = object.isNullConstant() ? OFF_HEAP_LOCATION : LocationIdentity.any();
             b.add(new RawStoreNode(object, offset, value, kind, locationIdentity));
-            if (isVolatile) {
-                b.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
+            if (hasBarrier) {
+                b.add(new MembarNode(postWrite));
             }
             b.getGraph().markUnsafeAccess();
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,19 +22,16 @@
  */
 package org.graalvm.compiler.replacements.classfile;
 
-import static org.graalvm.compiler.serviceprovider.JDK9Method.getModule;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.getResourceAsStream;
-
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
-import org.graalvm.compiler.serviceprovider.JDK9Method;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -98,20 +95,6 @@
         return false;
     }
 
-    private static InputStream getClassfileAsStream(Class<?> c) {
-        String classfilePath = c.getName().replace('.', '/') + ".class";
-        if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) {
-            Object module = getModule(c);
-            return getResourceAsStream(module, classfilePath);
-        } else {
-            ClassLoader cl = c.getClassLoader();
-            if (cl == null) {
-                return ClassLoader.getSystemResourceAsStream(classfilePath);
-            }
-            return cl.getResourceAsStream(classfilePath);
-        }
-    }
-
     /**
      * Gets a {@link Classfile} created by parsing the class file bytes for {@code c}.
      *
@@ -123,7 +106,7 @@
         if (classfile == null) {
             try {
                 ResolvedJavaType type = metaAccess.lookupJavaType(c);
-                InputStream in = getClassfileAsStream(c);
+                InputStream in = GraalServices.getClassfileAsStream(c);
                 if (in != null) {
                     DataInputStream stream = new DataInputStream(in);
                     classfile = new Classfile(type, stream, this);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/D	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,102 @@
+diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
+index 88403c3..728297d 100644
+--- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
++++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
+@@ -138,7 +138,11 @@ public final class ClassfileBytecodeProvider implements BytecodeProvider {
+         return classfile;
+     }
+ 
+-    synchronized Class<?> resolveToClass(String descriptor) {
++    Class<?> resolveToClass(String descriptor) {
++        return resolveToClass(descriptor, false);
++    }
++
++    synchronized Class<?> resolveToClass(String descriptor, boolean initialize) {
+         Class<?> c = classes.get(descriptor);
+         if (c == null) {
+             if (descriptor.length() == 1) {
+@@ -155,7 +159,7 @@ public final class ClassfileBytecodeProvider implements BytecodeProvider {
+                     name = descriptor.replace('/', '.');
+                 }
+                 try {
+-                    c = Class.forName(name, true, loader);
++                    c = Class.forName(name, initialize, loader);
+                     classes.put(descriptor, c);
+                 } catch (ClassNotFoundException e) {
+                     throw new NoClassDefFoundError(descriptor);
+diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstant.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstant.java
+index 087f78b..bde2dd4 100644
+--- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstant.java
++++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstant.java
+@@ -70,8 +70,9 @@ abstract class ClassfileConstant {
+      * @param cp
+      * @param index
+      * @param opcode
++     * @param initialize
+      */
+-    public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode) {
++    public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode, boolean initialize) {
+     }
+ 
+     @Override
+@@ -90,15 +91,19 @@ abstract class ClassfileConstant {
+         }
+ 
+         @Override
+-        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode) {
+-            resolve(cp);
++        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode, boolean initialize) {
++            resolve(cp, initialize);
+         }
+ 
+         public ResolvedJavaType resolve(ClassfileConstantPool cp) throws GraalError {
++            return resolve(cp, false /* initialize */);
++        }
++
++        public ResolvedJavaType resolve(ClassfileConstantPool cp, boolean initialize) throws GraalError {
+             if (type == null) {
+                 String typeDescriptor = cp.get(Utf8.class, nameIndex).value;
+                 ClassfileBytecodeProvider context = cp.context;
+-                type = context.metaAccess.lookupJavaType(context.resolveToClass(typeDescriptor));
++                type = context.metaAccess.lookupJavaType(context.resolveToClass(typeDescriptor, initialize));
+             }
+             return type;
+         }
+@@ -116,8 +121,8 @@ abstract class ClassfileConstant {
+         }
+ 
+         @Override
+-        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode) {
+-            cp.get(ClassRef.class, classIndex).loadReferencedType(cp, classIndex, opcode);
++        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode, boolean initialize) {
++            cp.get(ClassRef.class, classIndex).loadReferencedType(cp, classIndex, opcode, initialize);
+         }
+     }
+ 
+@@ -269,7 +274,7 @@ abstract class ClassfileConstant {
+         }
+ 
+         @Override
+-        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode) {
++        public void loadReferencedType(ClassfileConstantPool cp, int index, int opcode, boolean initialize) {
+             throw new GraalError("Resolution of " + name + " constant pool entries not supported by " + ClassfileBytecodeProvider.class.getSimpleName());
+         }
+     }
+diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstantPool.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstantPool.java
+index 218df10..a54779b 100644
+--- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstantPool.java
++++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstantPool.java
+@@ -133,11 +133,11 @@ class ClassfileConstantPool implements ConstantPool {
+     }
+ 
+     @Override
+-    public void loadReferencedType(int index, int opcode) {
++    public void loadReferencedType(int index, int opcode, boolean initialize) {
+         if (opcode == Bytecodes.INVOKEDYNAMIC) {
+             throw new GraalError("INVOKEDYNAMIC not supported by " + ClassfileBytecodeProvider.class.getSimpleName());
+         }
+-        entries[index].loadReferencedType(this, index, opcode);
++        entries[index].loadReferencedType(this, index, opcode, initialize);
+     }
+ 
+     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -44,7 +44,7 @@
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -46,7 +46,7 @@
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.InputType.State;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.debug.DebugContext;
@@ -51,7 +51,7 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.JavaKind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -189,7 +189,7 @@
                     ((Lowerable) nonNullReceiver).lower(tool);
                 }
             }
-            InliningUtil.inline(invoke, replacementGraph, false, targetMethod);
+            InliningUtil.inline(invoke, replacementGraph, false, targetMethod, "Replace with graph.", "LoweringPhase");
             replacementGraph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph(), "After inlining replacement %s", replacementGraph);
         } else {
             if (isPlaceholderBci(invoke.bci())) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java	Tue Apr 24 09:04:57 2018 -0700
@@ -36,7 +36,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,53 +22,44 @@
  */
 package org.graalvm.compiler.serviceprovider;
 
-import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.addOpens;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.getModule;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.getPackages;
-import static org.graalvm.compiler.serviceprovider.JDK9Method.isOpenTo;
+import static java.lang.Thread.currentThread;
 
-import java.lang.reflect.Method;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Iterator;
+import java.util.List;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
-import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
 
 import jdk.vm.ci.services.JVMCIPermission;
 import jdk.vm.ci.services.Services;
 
 /**
- * A mechanism for accessing service providers that abstracts over whether Graal is running on
- * JVMCI-8 or JVMCI-9. In JVMCI-8, a JVMCI specific mechanism is used to lookup services via the
- * hidden JVMCI class loader. In JVMCI-9, the standard {@link ServiceLoader} mechanism is used.
+ * Interface to functionality that abstracts over which JDK version Graal is running on.
  */
 public final class GraalServices {
 
-    private GraalServices() {
+    private static int getJavaSpecificationVersion() {
+        String value = System.getProperty("java.specification.version");
+        if (value.startsWith("1.")) {
+            value = value.substring(2);
+        }
+        return Integer.parseInt(value);
     }
 
     /**
-     * Opens all JVMCI packages to the module of a given class. This relies on JVMCI already having
-     * opened all its packages to the module defining {@link GraalServices}.
-     *
-     * @param other all JVMCI packages will be opened to the module defining this class
+     * The integer value corresponding to the value of the {@code java.specification.version} system
+     * property after any leading {@code "1."} has been stripped.
      */
-    public static void openJVMCITo(Class<?> other) {
-        Object jvmci = getModule(Services.class);
-        Object otherModule = getModule(other);
-        if (jvmci != otherModule) {
-            Set<String> packages = getPackages(jvmci);
-            for (String pkg : packages) {
-                boolean opened = isOpenTo(jvmci, pkg, otherModule);
-                if (!opened) {
-                    try {
-                        addOpens.invoke(jvmci, pkg, otherModule);
-                    } catch (Throwable throwable) {
-                        throw new InternalError(throwable);
-                    }
-                }
-            }
-        }
+    public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
+
+    /**
+     * Determines if the Java runtime is version 8 or earlier.
+     */
+    public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8;
+
+    private GraalServices() {
     }
 
     /**
@@ -79,15 +70,12 @@
      */
     public static <S> Iterable<S> load(Class<S> service) {
         assert !service.getName().startsWith("jdk.vm.ci") : "JVMCI services must be loaded via " + Services.class.getName();
-        if (Java8OrEarlier) {
-            return load8(service);
-        }
         Iterable<S> iterable = ServiceLoader.load(service);
-        return new Iterable<S>() {
+        return new Iterable<>() {
             @Override
             public Iterator<S> iterator() {
                 Iterator<S> iterator = iterable.iterator();
-                return new Iterator<S>() {
+                return new Iterator<>() {
                     @Override
                     public boolean hasNext() {
                         return iterator.hasNext();
@@ -111,19 +99,20 @@
     }
 
     /**
-     * {@code Services.load(Class)} is only defined in JVMCI-8.
+     * Opens all JVMCI packages to the module of a given class. This relies on JVMCI already having
+     * opened all its packages to the module defining {@link GraalServices}.
+     *
+     * @param other all JVMCI packages will be opened to the module defining this class
      */
-    private static volatile Method loadMethod;
-
-    @SuppressWarnings("unchecked")
-    private static <S> Iterable<S> load8(Class<S> service) throws InternalError {
-        try {
-            if (loadMethod == null) {
-                loadMethod = Services.class.getMethod("load", Class.class);
+    static void openJVMCITo(Class<?> other) {
+        Module jvmciModule = JVMCI_MODULE;
+        Module otherModule = other.getModule();
+        if (jvmciModule != otherModule) {
+            for (String pkg : jvmciModule.getPackages()) {
+                if (!jvmciModule.isOpen(pkg, otherModule)) {
+                    jvmciModule.addOpens(pkg, otherModule);
+                }
             }
-            return (Iterable<S>) loadMethod.invoke(null, service);
-        } catch (Exception e) {
-            throw new InternalError(e);
         }
     }
 
@@ -159,4 +148,185 @@
         }
         return singleProvider;
     }
+
+    /**
+     * Gets the class file bytes for {@code c}.
+     */
+    public static InputStream getClassfileAsStream(Class<?> c) throws IOException {
+        String classfilePath = c.getName().replace('.', '/') + ".class";
+        return c.getModule().getResourceAsStream(classfilePath);
+    }
+
+    private static final Module JVMCI_MODULE = Services.class.getModule();
+
+    /**
+     * A JVMCI package dynamically exported to trusted modules.
+     */
+    private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime";
+    static {
+        assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE);
+    }
+
+    /**
+     * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run
+     * trusted code.
+     */
+    public static boolean isToStringTrusted(Class<?> c) {
+        Module module = c.getModule();
+        Module jvmciModule = JVMCI_MODULE;
+        assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime");
+        if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) {
+            // Can access non-statically-exported package in JVMCI
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets a unique identifier for this execution such as a process ID or a
+     * {@linkplain #getGlobalTimeStamp() fixed timestamp}.
+     */
+    public static String getExecutionID() {
+        return Long.toString(ProcessHandle.current().pid());
+    }
+
+    private static final AtomicLong globalTimeStamp = new AtomicLong();
+
+    /**
+     * Gets a time stamp for the current process. This method will always return the same value for
+     * the current VM execution.
+     */
+    public static long getGlobalTimeStamp() {
+        if (globalTimeStamp.get() == 0) {
+            globalTimeStamp.compareAndSet(0, System.currentTimeMillis());
+        }
+        return globalTimeStamp.get();
+    }
+
+    /**
+     * Access to thread specific information made available via Java Management Extensions (JMX).
+     * Using this abstraction enables avoiding a dependency to the {@code java.management} and
+     * {@code jdk.management} modules on JDK 9 and later.
+     */
+    public abstract static class JMXService {
+        protected abstract long getThreadAllocatedBytes(long id);
+
+        protected abstract long getCurrentThreadCpuTime();
+
+        protected abstract boolean isThreadAllocatedMemorySupported();
+
+        protected abstract boolean isCurrentThreadCpuTimeSupported();
+
+        protected abstract List<String> getInputArguments();
+
+        // Placing this static field in JMXService (instead of GraalServices)
+        // allows for lazy initialization.
+        static final JMXService instance = loadSingle(JMXService.class, false);
+    }
+
+    /**
+     * Returns an approximation of the total amount of memory, in bytes, allocated in heap memory
+     * for the thread of the specified ID. The returned value is an approximation because some Java
+     * virtual machine implementations may use object allocation mechanisms that result in a delay
+     * between the time an object is allocated and the time its size is recorded.
+     * <p>
+     * If the thread of the specified ID is not alive or does not exist, this method returns
+     * {@code -1}. If thread memory allocation measurement is disabled, this method returns
+     * {@code -1}. A thread is alive if it has been started and has not yet died.
+     * <p>
+     * If thread memory allocation measurement is enabled after the thread has started, the Java
+     * virtual machine implementation may choose any time up to and including the time that the
+     * capability is enabled as the point where thread memory allocation measurement starts.
+     *
+     * @param id the thread ID of a thread
+     * @return an approximation of the total memory allocated, in bytes, in heap memory for a thread
+     *         of the specified ID if the thread of the specified ID exists, the thread is alive,
+     *         and thread memory allocation measurement is enabled; {@code -1} otherwise.
+     *
+     * @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
+     * @throws UnsupportedOperationException if the Java virtual machine implementation does not
+     *             {@linkplain #isThreadAllocatedMemorySupported() support} thread memory allocation
+     *             measurement.
+     */
+    public static long getThreadAllocatedBytes(long id) {
+        JMXService jmx = JMXService.instance;
+        if (jmx == null) {
+            throw new UnsupportedOperationException();
+        }
+        return jmx.getThreadAllocatedBytes(id);
+    }
+
+    /**
+     * Convenience method for calling {@link #getThreadAllocatedBytes(long)} with the id of the
+     * current thread.
+     */
+    public static long getCurrentThreadAllocatedBytes() {
+        return getThreadAllocatedBytes(currentThread().getId());
+    }
+
+    /**
+     * Returns the total CPU time for the current thread in nanoseconds. The returned value is of
+     * nanoseconds precision but not necessarily nanoseconds accuracy. If the implementation
+     * distinguishes between user mode time and system mode time, the returned CPU time is the
+     * amount of time that the current thread has executed in user mode or system mode.
+     *
+     * @return the total CPU time for the current thread if CPU time measurement is enabled;
+     *         {@code -1} otherwise.
+     *
+     * @throws UnsupportedOperationException if the Java virtual machine does not
+     *             {@linkplain #isCurrentThreadCpuTimeSupported() support} CPU time measurement for
+     *             the current thread
+     */
+    public static long getCurrentThreadCpuTime() {
+        JMXService jmx = JMXService.instance;
+        if (jmx == null) {
+            throw new UnsupportedOperationException();
+        }
+        return jmx.getCurrentThreadCpuTime();
+    }
+
+    /**
+     * Determines if the Java virtual machine implementation supports thread memory allocation
+     * measurement.
+     */
+    public static boolean isThreadAllocatedMemorySupported() {
+        JMXService jmx = JMXService.instance;
+        if (jmx == null) {
+            return false;
+        }
+        return jmx.isThreadAllocatedMemorySupported();
+    }
+
+    /**
+     * Determines if the Java virtual machine supports CPU time measurement for the current thread.
+     */
+    public static boolean isCurrentThreadCpuTimeSupported() {
+        JMXService jmx = JMXService.instance;
+        if (jmx == null) {
+            return false;
+        }
+        return jmx.isCurrentThreadCpuTimeSupported();
+    }
+
+    /**
+     * Gets the input arguments passed to the Java virtual machine which does not include the
+     * arguments to the {@code main} method. This method returns an empty list if there is no input
+     * argument to the Java virtual machine.
+     * <p>
+     * Some Java virtual machine implementations may take input arguments from multiple different
+     * sources: for examples, arguments passed from the application that launches the Java virtual
+     * machine such as the 'java' command, environment variables, configuration files, etc.
+     * <p>
+     * Typically, not all command-line options to the 'java' command are passed to the Java virtual
+     * machine. Thus, the returned input arguments may not include all command-line options.
+     *
+     * @return the input arguments to the JVM or {@code null} if they are unavailable
+     */
+    public static List<String> getInputArguments() {
+        JMXService jmx = JMXService.instance;
+        if (jmx == null) {
+            return null;
+        }
+        return jmx.getInputArguments();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.serviceprovider;
-
-import java.io.InputStream;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-/**
- * Reflection based access to API introduced by JDK 9. This allows the API to be used in code that
- * must be compiled on a JDK prior to 9.
- */
-public final class JDK9Method {
-
-    private static int getJavaSpecificationVersion() {
-        String value = System.getProperty("java.specification.version");
-        if (value.startsWith("1.")) {
-            value = value.substring(2);
-        }
-        return Integer.parseInt(value);
-    }
-
-    /**
-     * The integer value corresponding to the value of the {@code java.specification.version} system
-     * property after any leading {@code "1."} has been stripped.
-     */
-    public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
-
-    public static MethodHandle lookupMethodHandle(Class<?> declaringClass, String name, Class<?>... parameterTypes) {
-        try {
-            return MethodHandles.lookup().unreflect(declaringClass.getMethod(name, parameterTypes));
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private static Method lookupMethod(Class<?> declaringClass, String name, Class<?>... parameterTypes) {
-        try {
-            return declaringClass.getMethod(name, parameterTypes);
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-    }
-
-    /**
-     * Determines if the Java runtime is version 8 or earlier.
-     */
-    public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8;
-
-    /**
-     * {@code Class.getModule()}.
-     */
-    private static final MethodHandle getModuleHandle;
-
-    public static Object getModule(Class<?> clazz) {
-        try {
-            return getModuleHandle.invoke(clazz);
-        } catch (Throwable throwable) {
-            throw new InternalError(throwable);
-        }
-    }
-
-    /**
-     * {@code java.lang.Module.getPackages()}.
-     */
-    private static final MethodHandle getPackages;
-
-    public static Set<String> getPackages(Object module) {
-        try {
-            return (Set<String>) getPackages.invoke(module);
-        } catch (Throwable throwable) {
-            throw new InternalError(throwable);
-        }
-    }
-
-    /**
-     * {@code java.lang.Module.getResourceAsStream(String)}.
-     */
-    private static final MethodHandle getResourceAsStream;
-
-    public static InputStream getResourceAsStream(Object module, String resource) {
-        try {
-            return (InputStream) getResourceAsStream.invoke(module, resource);
-        } catch (Throwable throwable) {
-            throw new InternalError(throwable);
-        }
-    }
-
-    /**
-     * {@code java.lang.Module.addOpens(String, Module)}. This only seems to work correctly when
-     * invoked through reflection.
-     */
-    public static final Method addOpens;
-
-    /**
-     * {@code java.lang.Module.isOpen(String, Module)}.
-     */
-    private static final MethodHandle isOpenTo;
-
-    public static boolean isOpenTo(Object module1, String pkg, Object module2) {
-        try {
-            return (boolean) isOpenTo.invoke(module1, pkg, module2);
-        } catch (Throwable throwable) {
-            throw new InternalError(throwable);
-        }
-    }
-
-    public static final Class<?> MODULE_CLASS;
-
-    static {
-        if (JAVA_SPECIFICATION_VERSION >= 9) {
-            try {
-                MODULE_CLASS = Class.class.getMethod("getModule").getReturnType();
-                getModuleHandle = lookupMethodHandle(Class.class, "getModule");
-                getPackages = lookupMethodHandle(MODULE_CLASS, "getPackages");
-                addOpens = lookupMethod(MODULE_CLASS, "addOpens", String.class, MODULE_CLASS);
-                getResourceAsStream = lookupMethodHandle(MODULE_CLASS, "getResourceAsStream", String.class);
-                isOpenTo = lookupMethodHandle(MODULE_CLASS, "isOpen", String.class, MODULE_CLASS);
-            } catch (NoSuchMethodException e) {
-                throw new InternalError(e);
-            }
-        } else {
-            MODULE_CLASS = null;
-            getModuleHandle = null;
-            getPackages = null;
-            addOpens = null;
-            getResourceAsStream = null;
-            isOpenTo = null;
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.GlobalMetrics;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.internal.ComparisonCriteria;
@@ -64,7 +65,7 @@
         }
     }
 
-    public static final boolean Java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
+    public static final boolean Java8OrEarlier = GraalServices.Java8OrEarlier;
 
     protected Method getMethod(String methodName) {
         return getMethod(getClass(), methodName);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -35,6 +35,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.graalvm.util.CollectionsUtil;
 
 /**
@@ -236,7 +237,7 @@
         return new Subprocess(command, process.waitFor(), output);
     }
 
-    private static final boolean isJava8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
+    private static final boolean isJava8OrEarlier = GraalServices.Java8OrEarlier;
 
     private static boolean hasArg(String optionName) {
         if (optionName.equals("-cp") || optionName.equals("-classpath")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual.bench/.checkstyle.exclude	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-src_gen
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsBlockState.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsBlockState.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.Iterator;
 import java.util.Map;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.UnmodifiableMapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
 
 public abstract class EffectsBlockState<T extends EffectsBlockState<T>> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,9 +25,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -62,7 +62,7 @@
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator;
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator.LoopInfo;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 public abstract class EffectsClosure<BlockT extends EffectsBlockState<BlockT>> extends EffectsPhase.Closure<BlockT> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.core.common.util.CompilationAlarm;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,8 +25,8 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.DebugContext;
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Tue Apr 24 09:04:57 2018 -0700
@@ -29,11 +29,11 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
-import org.graalvm.collections.Pair;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.graph.Node;
@@ -66,7 +66,7 @@
 import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.virtual.phases.ea.PEReadEliminationBlockState.ReadCacheEntry;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Tue Apr 24 09:04:57 2018 -0700
@@ -28,9 +28,9 @@
 import java.util.List;
 import java.util.function.IntUnaryOperator;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java	Tue Apr 24 09:04:57 2018 -0700
@@ -25,7 +25,7 @@
 import static org.graalvm.compiler.core.common.GraalOptions.EscapeAnalysisIterations;
 import static org.graalvm.compiler.core.common.GraalOptions.EscapeAnalyzeOnly;
 
-import org.graalvm.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationBlockState.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationBlockState.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,10 +24,10 @@
 
 import java.util.Iterator;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 /**
  * This class maintains a set of known values, identified by base object, locations and offset.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Tue Apr 24 09:04:57 2018 -0700
@@ -23,15 +23,15 @@
 package org.graalvm.compiler.virtual.phases.ea;
 
 import static org.graalvm.compiler.core.common.GraalOptions.ReadEliminationMaxLoopVisits;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.util.Iterator;
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.MapCursor;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.MapCursor;
 import org.graalvm.compiler.core.common.cfg.Loop;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
@@ -63,7 +63,7 @@
 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.CacheEntry;
 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry;
 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry;
-import org.graalvm.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualUtil.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualUtil.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 
 import java.util.List;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.TTY;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/BarrieredAccess.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/BarrieredAccess.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,11 +24,11 @@
 
 import org.graalvm.compiler.word.Word.Opcode;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.SignedWord;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordBase;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.SignedWord;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordBase;
 
 /**
  * Medium-level memory access for Objects. Similarly to the readXxx and writeXxx methods defined for
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/ObjectAccess.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/ObjectAccess.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,11 +24,11 @@
 
 import org.graalvm.compiler.word.Word.Opcode;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.SignedWord;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordBase;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.SignedWord;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordBase;
 
 /**
  * Low-level memory access for Objects. Similarly to the readXxx and writeXxx methods defined for
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java	Tue Apr 24 09:04:57 2018 -0700
@@ -48,19 +48,19 @@
 import org.graalvm.compiler.nodes.calc.XorNode;
 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
 import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
-import org.graalvm.word.ComparableWord;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.Pointer;
-import org.graalvm.word.SignedWord;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.ComparableWord;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.SignedWord;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
+import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
 
-public abstract class Word extends WordFactory implements SignedWord, UnsignedWord, Pointer {
+public abstract class Word implements SignedWord, UnsignedWord, Pointer {
 
     static {
-        assert WordFactory.boxFactory == null : "BoxFactory must be initialized only once.";
-        WordFactory.boxFactory = new BoxFactoryImpl();
+        BoxFactoryImpl.initialize();
     }
 
     public static void ensureInitialized() {
@@ -109,10 +109,15 @@
         TO_RAW_VALUE,
     }
 
-    public static class BoxFactoryImpl implements BoxFactory {
+    static class BoxFactoryImpl extends WordBoxFactory {
+        static void initialize() {
+            assert boxFactory == null : "BoxFactory must be initialized only once.";
+            boxFactory = new BoxFactoryImpl();
+        }
+
         @SuppressWarnings("unchecked")
         @Override
-        public <T extends WordBase> T box(long val) {
+        public <T extends WordBase> T boxImpl(long val) {
             return (T) HostedWord.boxLong(val);
         }
     }
@@ -697,55 +702,55 @@
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public byte readByte(int offset, LocationIdentity locationIdentity) {
-        return readByte(signed(offset), locationIdentity);
+        return readByte(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public char readChar(int offset, LocationIdentity locationIdentity) {
-        return readChar(signed(offset), locationIdentity);
+        return readChar(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public short readShort(int offset, LocationIdentity locationIdentity) {
-        return readShort(signed(offset), locationIdentity);
+        return readShort(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public int readInt(int offset, LocationIdentity locationIdentity) {
-        return readInt(signed(offset), locationIdentity);
+        return readInt(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public long readLong(int offset, LocationIdentity locationIdentity) {
-        return readLong(signed(offset), locationIdentity);
+        return readLong(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public float readFloat(int offset, LocationIdentity locationIdentity) {
-        return readFloat(signed(offset), locationIdentity);
+        return readFloat(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public double readDouble(int offset, LocationIdentity locationIdentity) {
-        return readDouble(signed(offset), locationIdentity);
+        return readDouble(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public <T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity) {
-        return readWord(signed(offset), locationIdentity);
+        return readWord(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public Object readObject(int offset, LocationIdentity locationIdentity) {
-        return readObject(signed(offset), locationIdentity);
+        return readObject(WordFactory.signed(offset), locationIdentity);
     }
 
     @Override
@@ -809,61 +814,61 @@
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeByte(int offset, byte val, LocationIdentity locationIdentity) {
-        writeByte(signed(offset), val, locationIdentity);
+        writeByte(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeChar(int offset, char val, LocationIdentity locationIdentity) {
-        writeChar(signed(offset), val, locationIdentity);
+        writeChar(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeShort(int offset, short val, LocationIdentity locationIdentity) {
-        writeShort(signed(offset), val, locationIdentity);
+        writeShort(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeInt(int offset, int val, LocationIdentity locationIdentity) {
-        writeInt(signed(offset), val, locationIdentity);
+        writeInt(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeLong(int offset, long val, LocationIdentity locationIdentity) {
-        writeLong(signed(offset), val, locationIdentity);
+        writeLong(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeFloat(int offset, float val, LocationIdentity locationIdentity) {
-        writeFloat(signed(offset), val, locationIdentity);
+        writeFloat(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeDouble(int offset, double val, LocationIdentity locationIdentity) {
-        writeDouble(signed(offset), val, locationIdentity);
+        writeDouble(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeWord(int offset, WordBase val, LocationIdentity locationIdentity) {
-        writeWord(signed(offset), val, locationIdentity);
+        writeWord(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.INITIALIZE)
     public void initializeLong(int offset, long val, LocationIdentity locationIdentity) {
-        initializeLong(signed(offset), val, locationIdentity);
+        initializeLong(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeObject(int offset, Object val, LocationIdentity locationIdentity) {
-        writeObject(signed(offset), val, locationIdentity);
+        writeObject(WordFactory.signed(offset), val, locationIdentity);
     }
 
     @Override
@@ -924,60 +929,60 @@
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public byte readByte(int offset) {
-        return readByte(signed(offset));
+        return readByte(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public char readChar(int offset) {
-        return readChar(signed(offset));
+        return readChar(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public short readShort(int offset) {
-        return readShort(signed(offset));
+        return readShort(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public int readInt(int offset) {
-        return readInt(signed(offset));
+        return readInt(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public long readLong(int offset) {
-        return readLong(signed(offset));
+        return readLong(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public float readFloat(int offset) {
-        return readFloat(signed(offset));
+        return readFloat(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public double readDouble(int offset) {
-        return readDouble(signed(offset));
+        return readDouble(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public <T extends WordBase> T readWord(int offset) {
-        return readWord(signed(offset));
+        return readWord(WordFactory.signed(offset));
     }
 
     @Override
     @Operation(opcode = Opcode.READ_POINTER)
     public Object readObject(int offset) {
-        return readObject(signed(offset));
+        return readObject(WordFactory.signed(offset));
     }
 
     @Operation(opcode = Opcode.READ_HEAP)
     public Object readObject(int offset, BarrierType barrierType) {
-        return readObject(signed(offset), barrierType);
+        return readObject(WordFactory.signed(offset), barrierType);
     }
 
     @Override
@@ -1073,103 +1078,103 @@
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeByte(int offset, byte val) {
-        writeByte(signed(offset), val);
+        writeByte(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeChar(int offset, char val) {
-        writeChar(signed(offset), val);
+        writeChar(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeShort(int offset, short val) {
-        writeShort(signed(offset), val);
+        writeShort(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeInt(int offset, int val) {
-        writeInt(signed(offset), val);
+        writeInt(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeLong(int offset, long val) {
-        writeLong(signed(offset), val);
+        writeLong(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeFloat(int offset, float val) {
-        writeFloat(signed(offset), val);
+        writeFloat(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeDouble(int offset, double val) {
-        writeDouble(signed(offset), val);
+        writeDouble(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeWord(int offset, WordBase val) {
-        writeWord(signed(offset), val);
+        writeWord(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.WRITE_POINTER)
     public void writeObject(int offset, Object val) {
-        writeObject(signed(offset), val);
+        writeObject(WordFactory.signed(offset), val);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity) {
-        return compareAndSwapInt(signed(offset), expectedValue, newValue, locationIdentity);
+        return compareAndSwapInt(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity) {
-        return compareAndSwapLong(signed(offset), expectedValue, newValue, locationIdentity);
+        return compareAndSwapLong(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity) {
-        return compareAndSwapWord(signed(offset), expectedValue, newValue, locationIdentity);
+        return compareAndSwapWord(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity) {
-        return compareAndSwapObject(signed(offset), expectedValue, newValue, locationIdentity);
+        return compareAndSwapObject(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity) {
-        return logicCompareAndSwapInt(signed(offset), expectedValue, newValue, locationIdentity);
+        return logicCompareAndSwapInt(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity) {
-        return logicCompareAndSwapLong(signed(offset), expectedValue, newValue, locationIdentity);
+        return logicCompareAndSwapLong(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity) {
-        return logicCompareAndSwapWord(signed(offset), expectedValue, newValue, locationIdentity);
+        return logicCompareAndSwapWord(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     @Override
     @Operation(opcode = Opcode.CAS_POINTER)
     public boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity) {
-        return logicCompareAndSwapObject(signed(offset), expectedValue, newValue, locationIdentity);
+        return logicCompareAndSwapObject(WordFactory.signed(offset), expectedValue, newValue, locationIdentity);
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.nodes.ConstantNode.forInt;
 import static org.graalvm.compiler.nodes.ConstantNode.forIntegerKind;
-import static org.graalvm.word.LocationIdentity.any;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
 
 import java.lang.reflect.Constructor;
 import java.util.Arrays;
@@ -70,8 +70,8 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.word.Word.Opcode;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.impl.WordFactoryOperation;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.meta.JavaKind;
@@ -85,7 +85,7 @@
  * A plugin for calls to {@linkplain Operation word operations}, as well as all other nodes that
  * need special handling for {@link Word} types.
  */
-public class WordOperationPlugin extends WordFactory implements NodePlugin, TypePlugin, InlineInvokePlugin {
+public class WordOperationPlugin implements NodePlugin, TypePlugin, InlineInvokePlugin {
     protected final WordTypes wordTypes;
     protected final JavaKind wordKind;
     protected final SnippetReflectionProvider snippetReflection;
@@ -175,14 +175,14 @@
     }
 
     protected LoadIndexedNode createLoadIndexedNode(ValueNode array, ValueNode index) {
-        return new LoadIndexedNode(null, array, index, wordTypes.getWordKind());
+        return new LoadIndexedNode(null, array, index, wordKind);
     }
 
     @Override
     public boolean handleStoreField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field, ValueNode value) {
         if (field.getJavaKind() == JavaKind.Object) {
             boolean isWordField = wordTypes.isWord(field.getType());
-            boolean isWordValue = value.getStackKind() == wordTypes.getWordKind();
+            boolean isWordValue = value.getStackKind() == wordKind;
 
             if (isWordField && !isWordValue) {
                 throw bailout(b, "Cannot store a non-word value into a word field: " + field.format("%H.%n"));
@@ -205,20 +205,20 @@
         ResolvedJavaType arrayType = StampTool.typeOrNull(array);
         if (arrayType != null && wordTypes.isWord(arrayType.getComponentType())) {
             assert elementKind == JavaKind.Object;
-            if (value.getStackKind() != wordTypes.getWordKind()) {
+            if (value.getStackKind() != wordKind) {
                 throw bailout(b, "Cannot store a non-word value into a word array: " + arrayType.toJavaName(true));
             }
             b.add(createStoreIndexedNode(array, index, value));
             return true;
         }
-        if (elementKind == JavaKind.Object && value.getStackKind() == wordTypes.getWordKind()) {
+        if (elementKind == JavaKind.Object && value.getStackKind() == wordKind) {
             throw bailout(b, "Cannot store a word value into a non-word array: " + arrayType.toJavaName(true));
         }
         return false;
     }
 
     protected StoreIndexedNode createStoreIndexedNode(ValueNode array, ValueNode index, ValueNode value) {
-        return new StoreIndexedNode(array, index, wordTypes.getWordKind(), value);
+        return new StoreIndexedNode(array, index, wordKind, value);
     }
 
     @Override
@@ -230,7 +230,7 @@
             return false;
         }
 
-        if (object.getStackKind() != wordTypes.getWordKind()) {
+        if (object.getStackKind() != wordKind) {
             throw bailout(b, "Cannot cast a non-word value to a word type: " + type.toJavaName(true));
         }
         b.push(JavaKind.Object, object);
@@ -249,7 +249,7 @@
 
     protected void processWordOperation(GraphBuilderContext b, ValueNode[] args, ResolvedJavaMethod wordMethod) throws GraalError {
         JavaKind returnKind = wordMethod.getSignature().getReturnKind();
-        WordFactory.FactoryOperation factoryOperation = BridgeMethodUtils.getAnnotation(WordFactory.FactoryOperation.class, wordMethod);
+        WordFactoryOperation factoryOperation = BridgeMethodUtils.getAnnotation(WordFactoryOperation.class, wordMethod);
         if (factoryOperation != null) {
             switch (factoryOperation.opcode()) {
                 case ZERO:
@@ -510,10 +510,6 @@
         }
     }
 
-    public WordTypes getWordTypes() {
-        return wordTypes;
-    }
-
     private static BailoutException bailout(GraphBuilderContext b, String msg) {
         throw b.bailout(msg + "\nat " + b.getCode().asStackTraceElement(b.bci()));
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java	Tue Apr 24 09:04:57 2018 -0700
@@ -27,8 +27,8 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.word.Word.Operation;
-import org.graalvm.word.WordBase;
-import org.graalvm.word.WordFactory;
+import jdk.internal.vm.compiler.word.WordBase;
+import jdk.internal.vm.compiler.word.WordFactory;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphElements.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphElements.java	Tue Apr 24 09:04:57 2018 -0700
@@ -187,7 +187,10 @@
     int nodeSourcePositionBCI(P pos);
 
     /**
-     * Stack trace element for a method, index and position.
+     * Stack trace element for a method, index and position. This is the basic version of the method
+     * that works with {@link StackTraceElement} and is suitable for Java-like languages. Should you
+     * need to provide more details about the location of multiple strata, see
+     * {@link GraphLocations} interface that gives more control over the provided location data.
      *
      * @param method the method
      * @param bci the index
@@ -195,4 +198,5 @@
      * @return stack trace element for the method, index and position
      */
     StackTraceElement methodStackTraceElement(M method, int bci, P pos);
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphLocations.java	Tue Apr 24 09:04:57 2018 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.graphio;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Provides source location information about compiled code. This interface is an extension of
+ * {@link GraphElements} - by default the elements work with classical {@link StackTraceElement}.
+ * Should the default behavior not be sufficient, feel free to implement the additional operations
+ * available in this interface and register your implementation when {@link GraphOutput.Builder
+ * building} the {@link GraphOutput} instance.
+ *
+ * @param <M> type representing methods
+ * @param <P> type representing source code location
+ * @param <L> represeting {@link StackTraceElement stack element} location
+ *
+ * @since 0.33 part of GraalVM 0.33
+ */
+public interface GraphLocations<M, P, L> {
+    /**
+     * Stack trace element for a method, index and position. Returns all applicable source locations
+     * for given code position. Each provided location is expected to represent location in a
+     * different {@link #locationLanguage(java.lang.Object) language}.
+     *
+     * @param method the method
+     * @param bci the index
+     * @param pos the position
+     * @return elements representing location for all language strata
+     */
+    Iterable<L> methodLocation(M method, int bci, P pos);
+
+    /**
+     * Identification of the language. Each location can point to a source in a different language -
+     * e.g. each location can have multiple <em>strata</em>.
+     *
+     * @param location the location
+     * @return id of the language/strata
+     */
+    String locationLanguage(L location);
+
+    /**
+     * The universal resource identification that contains the location.If the location can be found
+     * in an assummably accessible resource, then use such resource identification. It is up to the
+     * side processing the URI to load the content from the location. Protocols scheme {@code file},
+     * {@code http}, or {@code https} are assumed to be accessible.
+     * <p>
+     * If the location is inside of a virtual source, or source which is unlikely to be accessible
+     * outside of running program, then it may be better to encode the whole source into the
+     * resource identifier. This can be done by using
+     * <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs">data
+     * URIs</a> like:
+     *
+     * <pre>
+     * data:text/javascript,alert('Vivat graphs!')
+     * </pre>
+     *
+     * @param location the location
+     * @return the file name for the given location or {@code null} if it is not known
+     * @throws URISyntaxException yielding this exception aborts the graph dumping
+     */
+    URI locationURI(L location) throws URISyntaxException;
+
+    /**
+     * Line number of a location. The first line in the source file is one. Negative value means the
+     * line location isn't available. In such situation one can provide an offset driven location
+     * co-ordinates via {@link #locationOffsetStart(java.lang.Object)} and
+     * {@link #locationOffsetEnd(java.lang.Object)} methods.
+     *
+     * @param location the location
+     * @return the line number for given location, negative value means no line
+     */
+    int locationLineNumber(L location);
+
+    /**
+     * Offset of the location. In certain situations it is preferrable to specify offset rather than
+     * {@link #locationLineNumber(java.lang.Object) line number} of a location in source. In such
+     * case return the start offset from this method and end offset via
+     * {@link #locationOffsetEnd(java.lang.Object)} method. Offsets are counted from {@code 0}.
+     *
+     * @param location the location
+     * @return the starting offset of the location, negative value means no offset
+     */
+    int locationOffsetStart(L location);
+
+    /**
+     * Offset of the location. In certain situations it is preferrable to specify offset rather than
+     * {@link #locationLineNumber(java.lang.Object) line number} of a location in source. In such
+     * case return the start offset via {@link #locationOffsetStart(java.lang.Object)} method and
+     * end from this method. Offsets are counted from {@code 0}.
+     *
+     * @param location the location
+     * @return the end offset (exclusive) of the location, negative value means no offset
+     */
+    int locationOffsetEnd(L location);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,7 +24,10 @@
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.channels.WritableByteChannel;
+import java.util.Collections;
 import java.util.Map;
 
 /**
@@ -34,9 +37,9 @@
  * @param <M> the type of methods this instance handles
  */
 public final class GraphOutput<G, M> implements Closeable {
-    private final GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> printer;
+    private final GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?, ?> printer;
 
-    private GraphOutput(GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> p) {
+    private GraphOutput(GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?, ?> p) {
         this.printer = p;
     }
 
@@ -110,7 +113,8 @@
      */
     public static final class Builder<G, N, M> {
         private final GraphStructure<G, N, ?, ?> structure;
-        private GraphElements<M, ?, ?, ?> elements = null;
+        private ElementsAndLocations<M, ?, ?> elementsAndLocations;
+
         private GraphTypes types = DefaultGraphTypes.DEFAULT;
         private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty();
         private int major = 4;
@@ -164,9 +168,24 @@
          * @param graphElements the elements implementation
          * @return this builder
          */
+        public <E, P> Builder<G, N, E> elements(GraphElements<E, ?, ?, P> graphElements) {
+            StackLocations<E, P> loc = new StackLocations<>(graphElements);
+            return elementsAndLocations(graphElements, loc);
+        }
+
+        /**
+         * Associates implementation of graph elements and an advanced way to interpret their
+         * locations.
+         *
+         * @param graphElements the elements implementation
+         * @param graphLocations the locations for the elements
+         * @return this builder
+         * @since 0.33 GraalVM 0.33
+         */
         @SuppressWarnings({"unchecked", "rawtypes"})
-        public <E> Builder<G, N, E> elements(GraphElements<E, ?, ?, ?> graphElements) {
-            this.elements = (GraphElements) graphElements;
+        public <E, P> Builder<G, N, E> elementsAndLocations(GraphElements<E, ?, ?, P> graphElements, GraphLocations<E, P, ?> graphLocations) {
+            ElementsAndLocations both = new ElementsAndLocations<>(graphElements, graphLocations);
+            this.elementsAndLocations = both;
             return (Builder<G, N, E>) this;
         }
 
@@ -179,8 +198,7 @@
          * @throws IOException if something goes wrong when writing to the channel
          */
         public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException {
-            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(major, minor, structure, types, blocks, elements, channel);
-            return new GraphOutput<>(p);
+            return buildImpl(elementsAndLocations, channel);
         }
 
         /**
@@ -200,8 +218,85 @@
          * @return new output sharing {@code channel} and other internals with {@code parent}
          */
         public GraphOutput<G, M> build(GraphOutput<?, ?> parent) {
-            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(parent.printer, structure, types, blocks, elements);
+            return buildImpl(elementsAndLocations, parent);
+        }
+
+        private <L, P> GraphOutput<G, M> buildImpl(ElementsAndLocations<M, L, P> e, WritableByteChannel channel) throws IOException {
+            // @formatter:off
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?, ?> p = new ProtocolImpl<>(
+                major, minor, structure, types, blocks,
+                e == null ? null : e.elements,
+                e == null ? null : e.locations, channel
+            );
+            // @formatter:on
+            return new GraphOutput<>(p);
+        }
+
+        private <L, P> GraphOutput<G, M> buildImpl(ElementsAndLocations<M, L, P> e, GraphOutput<?, ?> parent) {
+            // @formatter:off
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?, ?> p = new ProtocolImpl<>(
+                parent.printer, structure, types, blocks,
+                e == null ? null : e.elements,
+                e == null ? null : e.locations
+            );
+            // @formatter:on
             return new GraphOutput<>(p);
         }
     }
+
+    private static final class ElementsAndLocations<M, P, L> {
+        final GraphElements<M, ?, ?, P> elements;
+        final GraphLocations<M, P, L> locations;
+
+        ElementsAndLocations(GraphElements<M, ?, ?, P> elements, GraphLocations<M, P, L> locations) {
+            elements.getClass();
+            locations.getClass();
+            this.elements = elements;
+            this.locations = locations;
+        }
+    }
+
+    private static final class StackLocations<M, P> implements GraphLocations<M, P, StackTraceElement> {
+        private final GraphElements<M, ?, ?, P> graphElements;
+
+        StackLocations(GraphElements<M, ?, ?, P> graphElements) {
+            this.graphElements = graphElements;
+        }
+
+        @Override
+        public Iterable<StackTraceElement> methodLocation(M method, int bci, P pos) {
+            StackTraceElement ste = this.graphElements.methodStackTraceElement(method, bci, pos);
+            return Collections.singleton(ste);
+        }
+
+        @Override
+        public URI locationURI(StackTraceElement location) {
+            String path = location.getFileName();
+            try {
+                return path == null ? null : new URI(null, null, path, null);
+            } catch (URISyntaxException ex) {
+                throw new IllegalArgumentException(ex);
+            }
+        }
+
+        @Override
+        public int locationLineNumber(StackTraceElement location) {
+            return location.getLineNumber();
+        }
+
+        @Override
+        public String locationLanguage(StackTraceElement location) {
+            return "Java";
+        }
+
+        @Override
+        public int locationOffsetStart(StackTraceElement location) {
+            return -1;
+        }
+
+        @Override
+        public int locationOffsetEnd(StackTraceElement location) {
+            return -1;
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,16 +24,20 @@
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
 import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.Map;
+import java.util.Objects;
 
-abstract class GraphProtocol<Graph, Node, NodeClass, Edges, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> implements Closeable {
+abstract class GraphProtocol<Graph, Node, NodeClass, Edges, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition, Location> implements Closeable {
     private static final Charset UTF8 = Charset.forName("UTF-8");
 
     private static final int CONSTANT_POOL_MAX_SIZE = 8000;
@@ -76,7 +80,7 @@
     final int versionMinor;
 
     GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
-        if (major > 5 || (major == 5 && minor > 0)) {
+        if (major > 6 || (major == 6 && minor > 0)) {
             throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
         }
         this.versionMajor = major;
@@ -87,7 +91,7 @@
         writeVersion();
     }
 
-    GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
+    GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
         this.versionMajor = parent.versionMajor;
         this.versionMinor = parent.versionMinor;
         this.constantPool = parent.constantPool;
@@ -254,7 +258,19 @@
 
     protected abstract int findNodeSourcePositionBCI(NodeSourcePosition pos);
 
-    protected abstract StackTraceElement findMethodStackTraceElement(ResolvedJavaMethod method, int bci, NodeSourcePosition pos);
+    protected abstract Iterable<Location> findLocation(ResolvedJavaMethod method, int bci, NodeSourcePosition pos);
+
+    protected abstract String findLocationFile(Location loc) throws IOException;
+
+    protected abstract int findLocationLine(Location loc);
+
+    protected abstract URI findLocationURI(Location loc) throws URISyntaxException;
+
+    protected abstract String findLocationLanguage(Location loc);
+
+    protected abstract int findLocationStart(Location loc);
+
+    protected abstract int findLocationEnd(Location loc);
 
     private void writeVersion() throws IOException {
         writeBytesRaw(MAGIC_BYTES);
@@ -374,34 +390,57 @@
         if (id == null) {
             addPoolEntry(object);
         } else {
-            if (findJavaField(object) != null) {
-                writeByte(POOL_FIELD);
-            } else if (findSignature(object) != null) {
-                writeByte(POOL_SIGNATURE);
-            } else if (versionMajor >= 4 && findNodeSourcePosition(object) != null) {
-                writeByte(POOL_NODE_SOURCE_POSITION);
-            } else {
-                final Node node = findNode(object);
-                if (versionMajor == 4 && node != null) {
-                    object = classForNode(node);
+            int type = findPoolType(object, null);
+            writeByte(type);
+            writeShort(id.charValue());
+        }
+    }
+
+    private int findPoolType(Object obj, Object[] found) throws IOException {
+        Object object = obj;
+        if (object == null) {
+            return POOL_NULL;
+        }
+        if (isFound(findJavaField(object), found)) {
+            return POOL_FIELD;
+        } else if (isFound(findSignature(object), found)) {
+            return POOL_SIGNATURE;
+        } else if (versionMajor >= 4 && isFound(findNodeSourcePosition(object), found)) {
+            return POOL_NODE_SOURCE_POSITION;
+        } else {
+            final Node node = findNode(object);
+            if (versionMajor == 4 && node != null) {
+                object = classForNode(node);
+            }
+            if (isFound(findNodeClass(object), found)) {
+                return POOL_NODE_CLASS;
+            } else if (versionMajor >= 5 && isFound(node, found)) {
+                return POOL_NODE;
+            } else if (isFound(findMethod(object), found)) {
+                return POOL_METHOD;
+            } else if (object instanceof Enum<?>) {
+                if (found != null) {
+                    found[0] = ((Enum<?>) object).ordinal();
                 }
-                if (findNodeClass(object) != null) {
-                    writeByte(POOL_NODE_CLASS);
-                } else if (versionMajor >= 5 && node != null) {
-                    writeByte(POOL_NODE);
-                } else if (findMethod(object) != null) {
-                    writeByte(POOL_METHOD);
+                return POOL_ENUM;
+            } else {
+                int val = findEnumOrdinal(object);
+                if (val >= 0) {
+                    if (found != null) {
+                        found[0] = val;
+                    }
+                    return POOL_ENUM;
+                } else if (object instanceof Class<?>) {
+                    if (found != null) {
+                        found[0] = ((Class<?>) object).getName();
+                    }
+                    return POOL_CLASS;
+                } else if (isFound(findJavaTypeName(object), found)) {
+                    return POOL_CLASS;
                 } else {
-                    if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
-                        writeByte(POOL_ENUM);
-                    } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
-                        writeByte(POOL_CLASS);
-                    } else {
-                        writeByte(POOL_STRING);
-                    }
+                    return POOL_STRING;
                 }
             }
-            writeShort(id.charValue());
         }
     }
 
@@ -519,61 +558,89 @@
         }
     }
 
-    @SuppressWarnings("all")
+    @SuppressWarnings("unchecked")
     private void addPoolEntry(Object obj) throws IOException {
         Object object = obj;
-        ResolvedJavaField field;
-        String typeName;
-        Signature signature;
-        NodeSourcePosition pos;
-        int enumOrdinal;
         char index = constantPool.add(object);
         writeByte(POOL_NEW);
         writeShort(index);
-        if ((field = findJavaField(object)) != null) {
-            writeByte(POOL_FIELD);
-            writePoolObject(findFieldDeclaringClass(field));
-            writePoolObject(findFieldName(field));
-            writePoolObject(findFieldTypeName(field));
-            writeInt(findFieldModifiers(field));
-        } else if ((signature = findSignature(object)) != null) {
-            writeByte(POOL_SIGNATURE);
-            int args = findSignatureParameterCount(signature);
-            writeShort((char) args);
-            for (int i = 0; i < args; i++) {
-                writePoolObject(findSignatureParameterTypeName(signature, i));
+
+        Object[] found = {null};
+        int type = findPoolType(object, found);
+        writeByte(type);
+        switch (type) {
+            case POOL_FIELD: {
+                ResolvedJavaField field = (ResolvedJavaField) found[0];
+                Objects.nonNull(field);
+                writePoolObject(findFieldDeclaringClass(field));
+                writePoolObject(findFieldName(field));
+                writePoolObject(findFieldTypeName(field));
+                writeInt(findFieldModifiers(field));
+                break;
+            }
+            case POOL_SIGNATURE: {
+                Signature signature = (Signature) found[0];
+                int args = findSignatureParameterCount(signature);
+                writeShort((char) args);
+                for (int i = 0; i < args; i++) {
+                    writePoolObject(findSignatureParameterTypeName(signature, i));
+                }
+                writePoolObject(findSignatureReturnTypeName(signature));
+                break;
             }
-            writePoolObject(findSignatureReturnTypeName(signature));
-        } else if (versionMajor >= 4 && (pos = findNodeSourcePosition(object)) != null) {
-            writeByte(POOL_NODE_SOURCE_POSITION);
-            ResolvedJavaMethod method = findNodeSourcePositionMethod(pos);
-            writePoolObject(method);
-            final int bci = findNodeSourcePositionBCI(pos);
-            writeInt(bci);
-            StackTraceElement ste = findMethodStackTraceElement(method, bci, pos);
-            if (ste != null && ste.getFileName() != null) {
-                writePoolObject(ste.getFileName());
-                writeInt(ste.getLineNumber());
-            } else {
-                writePoolObject(null);
+            case POOL_NODE_SOURCE_POSITION: {
+                NodeSourcePosition pos = (NodeSourcePosition) found[0];
+                Objects.nonNull(pos);
+                ResolvedJavaMethod method = findNodeSourcePositionMethod(pos);
+                writePoolObject(method);
+                final int bci = findNodeSourcePositionBCI(pos);
+                writeInt(bci);
+                Iterator<Location> ste = findLocation(method, bci, pos).iterator();
+                if (versionMajor >= 6) {
+                    while (ste.hasNext()) {
+                        Location loc = ste.next();
+                        URI uri;
+                        try {
+                            uri = findLocationURI(loc);
+                        } catch (URISyntaxException ex) {
+                            throw new IOException(ex);
+                        }
+                        if (uri == null) {
+                            throw new IOException("No URI for " + loc);
+                        }
+                        String l = findLocationLanguage(loc);
+                        if (l == null) {
+                            continue;
+                        }
+                        writePoolObject(uri.toString());
+                        writeString(l);
+                        writeInt(findLocationLine(loc));
+                        writeInt(findLocationStart(loc));
+                        writeInt(findLocationEnd(loc));
+                    }
+                    writePoolObject(null);
+                } else {
+                    Location first = ste.hasNext() ? ste.next() : null;
+                    String fileName = first != null ? findLocationFile(first) : null;
+                    if (fileName != null) {
+                        writePoolObject(fileName);
+                        writeInt(findLocationLine(first));
+                    } else {
+                        writePoolObject(null);
+                    }
+                }
+                writePoolObject(findNodeSourcePositionCaller(pos));
+                break;
             }
-            writePoolObject(findNodeSourcePositionCaller(pos));
-        } else {
-            Node node = findNode(object);
-            if (node != null) {
-                if (versionMajor >= 5) {
-                    writeByte(POOL_NODE);
-                    writeInt(findNodeId(node));
-                    writePoolObject(classForNode(node));
-                    return;
-                }
-                if (versionMajor == 4) {
-                    object = classForNode(node);
-                }
+            case POOL_NODE: {
+                Node node = (Node) found[0];
+                Objects.nonNull(node);
+                writeInt(findNodeId(node));
+                writePoolObject(classForNode(node));
+                break;
             }
-            NodeClass nodeClass = findNodeClass(object);
-            if (nodeClass != null) {
-                writeByte(POOL_NODE_CLASS);
+            case POOL_NODE_CLASS: {
+                NodeClass nodeClass = (NodeClass) found[0];
                 final Object clazz = findJavaClass(nodeClass);
                 if (versionMajor >= 3) {
                     writePoolObject(clazz);
@@ -585,39 +652,50 @@
                 }
                 writeEdgesInfo(nodeClass, true);
                 writeEdgesInfo(nodeClass, false);
-                return;
+                break;
             }
-            ResolvedJavaMethod method = findMethod(object);
-            if (method == null) {
-                if ((typeName = findJavaTypeName(object)) != null) {
-                    writeByte(POOL_CLASS);
-                    writeString(typeName);
-                    String[] enumValueNames = findEnumTypeValues(object);
-                    if (enumValueNames != null) {
-                        writeByte(ENUM_KLASS);
-                        writeInt(enumValueNames.length);
-                        for (String o : enumValueNames) {
-                            writePoolObject(o);
-                        }
-                    } else {
-                        writeByte(KLASS);
+            case POOL_CLASS: {
+                String typeName = (String) found[0];
+                Objects.nonNull(typeName);
+                writeString(typeName);
+                String[] enumValueNames = findEnumTypeValues(object);
+                if (enumValueNames != null) {
+                    writeByte(ENUM_KLASS);
+                    writeInt(enumValueNames.length);
+                    for (String o : enumValueNames) {
+                        writePoolObject(o);
                     }
-                } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
-                    writeByte(POOL_ENUM);
-                    writePoolObject(findEnumClass(object));
-                    writeInt(enumOrdinal);
                 } else {
-                    writeByte(POOL_STRING);
-                    writeString(object.toString());
+                    writeByte(KLASS);
+                }
+                break;
+            }
+            case POOL_METHOD: {
+                ResolvedJavaMethod method = (ResolvedJavaMethod) found[0];
+                Objects.nonNull(method);
+                writePoolObject(findMethodDeclaringClass(method));
+                writePoolObject(findMethodName(method));
+                final Signature methodSignature = findMethodSignature(method);
+                if (findSignature(methodSignature) == null) {
+                    throw new IOException("Should be recognized as signature: " + methodSignature + " for " + method);
                 }
-                return;
+                writePoolObject(methodSignature);
+                writeInt(findMethodModifiers(method));
+                writeBytes(findMethodCode(method));
+                break;
             }
-            writeByte(POOL_METHOD);
-            writePoolObject(findMethodDeclaringClass(method));
-            writePoolObject(findMethodName(method));
-            writePoolObject(findMethodSignature(method));
-            writeInt(findMethodModifiers(method));
-            writeBytes(findMethodCode(method));
+            case POOL_ENUM: {
+                int enumOrdinal = (int) found[0];
+                writePoolObject(findEnumClass(object));
+                writeInt(enumOrdinal);
+                break;
+            }
+            case POOL_STRING: {
+                writeString(object.toString());
+                break;
+            }
+            default:
+                throw new IllegalStateException();
         }
     }
 
@@ -696,6 +774,16 @@
         }
     }
 
+    private static boolean isFound(Object obj, Object[] found) {
+        if (obj == null) {
+            return false;
+        }
+        if (found != null) {
+            found[0] = obj;
+        }
+        return true;
+    }
+
     private static final class ConstantPool extends LinkedHashMap<Object, Character> {
 
         private final LinkedList<Character> availableIds;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Tue Apr 24 09:04:57 2018 -0700
@@ -22,34 +22,43 @@
  */
 package org.graalvm.graphio;
 
+import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.channels.WritableByteChannel;
 import java.util.Collection;
 import java.util.Map;
 
-final class ProtocolImpl<Graph, Node, NodeClass, Port, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition>
-                extends GraphProtocol<Graph, Node, NodeClass, Port, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> {
+final class ProtocolImpl<Graph, Node, NodeClass, Port, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition, Location>
+                extends GraphProtocol<Graph, Node, NodeClass, Port, Block, ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition, Location> {
     private final GraphStructure<Graph, Node, NodeClass, Port> structure;
     private final GraphTypes types;
     private final GraphBlocks<Graph, Block, Node> blocks;
     private final GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements;
+    private final GraphLocations<ResolvedJavaMethod, NodeSourcePosition, Location> locations;
 
     ProtocolImpl(int major, int minor, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
-                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements, WritableByteChannel channel) throws IOException {
+                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements,
+                    GraphLocations<ResolvedJavaMethod, NodeSourcePosition, Location> locs,
+                    WritableByteChannel channel) throws IOException {
         super(channel, major, minor);
         this.structure = structure;
         this.types = enums;
         this.blocks = blocks;
         this.elements = elements;
+        this.locations = locs;
     }
 
-    ProtocolImpl(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
-                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements) {
+    ProtocolImpl(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> parent, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements,
+                    GraphLocations<ResolvedJavaMethod, NodeSourcePosition, Location> locs) {
         super(parent);
         this.structure = structure;
         this.types = enums;
         this.blocks = blocks;
         this.elements = elements;
+        this.locations = locs;
     }
 
     @Override
@@ -285,8 +294,56 @@
     }
 
     @Override
-    protected StackTraceElement findMethodStackTraceElement(ResolvedJavaMethod method, int bci, NodeSourcePosition pos) {
-        return elements.methodStackTraceElement(method, bci, pos);
+    protected Iterable<Location> findLocation(ResolvedJavaMethod method, int bci, NodeSourcePosition pos) {
+        return locations.methodLocation(method, bci, pos);
+    }
+
+    @Override
+    protected String findLocationFile(Location loc) throws IOException {
+        if (loc == null) {
+            return null;
+        }
+        URI u;
+        try {
+            u = locations.locationURI(loc);
+        } catch (URISyntaxException ex) {
+            throw new IOException(ex);
+        }
+        if (u == null) {
+            return null;
+        }
+        if (u.getScheme() == null) {
+            return u.getPath();
+        }
+        if ("file".equals(u.getScheme())) {
+            return new File(u).getPath();
+        }
+        return null;
+    }
+
+    @Override
+    protected int findLocationLine(Location loc) {
+        return locations.locationLineNumber(loc);
+    }
+
+    @Override
+    protected URI findLocationURI(Location loc) throws URISyntaxException {
+        return locations.locationURI(loc);
+    }
+
+    @Override
+    protected String findLocationLanguage(Location loc) {
+        return locations.locationLanguage(loc);
+    }
+
+    @Override
+    protected int findLocationStart(Location loc) {
+        return locations.locationOffsetStart(loc);
+    }
+
+    @Override
+    protected int findLocationEnd(Location loc) {
+        return locations.locationOffsetEnd(loc);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java	Tue Apr 24 09:04:57 2018 -0700
@@ -24,8 +24,8 @@
 
 import static org.junit.Assert.assertEquals;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.test.GraalTest;
 import org.graalvm.util.ObjectSizeEstimate;
 import org.junit.Assume;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/ObjectSizeEstimate.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/ObjectSizeEstimate.java	Tue Apr 24 09:04:57 2018 -0700
@@ -26,8 +26,8 @@
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 
 /**
  * Calculates approximate estimates of the size of an object graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +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: Checks
-    Description: none
--->
-<module name="Checker">
-  <property name="severity" value="error"/>
-  <module name="TreeWalker">
-    <module name="AvoidStarImport">
-      <property name="allowClassImports" value="false"/>
-      <property name="allowStaticMemberImports" value="false"/>
-    </module>
-    <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"/>
-    <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,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="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.comment" value="Checks for whitespace before a comma."/>
-      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="[^\x00-\x7F]"/>
-      <property name="message" value="Only use ASCII characters."/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
-      <property name="message" value="Don't use old synchronized collection classes"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof MoveOp"/>
-      <property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof ValueMoveOp"/>
-      <property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="instanceof LoadConstantOp"/>
-      <property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(MoveOp\)"/>
-      <property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(ValueMoveOp\)"/>
-      <property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <property name="format" value="\(LoadConstantOp\)"/>
-      <property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
-    </module>
-  </module>
-  <module name="RegexpHeader">
-    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.  Oracle designates this\n \* particular file as subject to the &quot;Classpath&quot; exception as provided\n \* by Oracle in the LICENSE file that accompanied this code.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
-    <property name="fileExtensions" value="java"/>
-  </module>
-  <module name="FileTabCharacter">
-    <property name="severity" value="error"/>
-    <property name="fileExtensions" value="java"/>
-  </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="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 name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
-    <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
-    <property name="checkFormat" value="LineLength"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: start generated"/>
-    <property name="onCommentFormat" value="CheckStyle: stop generated"/>
-    <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
-  </module>
-</module>
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/ComparableWord.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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.  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 org.graalvm.word;
-
-public interface ComparableWord extends WordBase {
-
-    /**
-     * Compares this word with the specified value.
-     *
-     * @param val value to which this word is to be compared.
-     * @return {@code this == val}
-     */
-    boolean equal(ComparableWord val);
-
-    /**
-     * Compares this word with the specified value.
-     *
-     * @param val value to which this word is to be compared.
-     * @return {@code this != val}
-     */
-    boolean notEqual(ComparableWord val);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/LocationIdentity.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.word;
-
-// JaCoCo Exclude
-
-/**
- * Marker interface for location identities. A different location identity of two memory accesses
- * guarantees that the two accesses do not interfere.
- *
- * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
- * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
- * {@link java.util.IdentityHashMap}s with {@link LocationIdentity} values as keys.
- */
-public abstract class LocationIdentity {
-
-    private static final class AnyLocationIdentity extends LocationIdentity {
-        @Override
-        public boolean isImmutable() {
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "ANY_LOCATION";
-        }
-    }
-
-    private static final class InitLocationIdentity extends LocationIdentity {
-        @Override
-        public boolean isImmutable() {
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            return "INIT_LOCATION";
-        }
-    }
-
-    public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
-    public static final LocationIdentity INIT_LOCATION = new InitLocationIdentity();
-
-    /**
-     * Indicates that the given location is the union of all possible mutable locations. A write to
-     * such a location kill all reads from mutable locations and a read from this location is killed
-     * by any write (except for initialization writes).
-     */
-    public static LocationIdentity any() {
-        return ANY_LOCATION;
-    }
-
-    /**
-     * Location only allowed to be used for writes. Indicates that a completely new memory location
-     * is written. Kills no read. The previous value at the given location must be either
-     * uninitialized or null. Writes to this location do not need a GC pre-barrier.
-     */
-    public static LocationIdentity init() {
-        return INIT_LOCATION;
-    }
-
-    /**
-     * Denotes a location is unchanging in all cases. Not that this is different than the Java
-     * notion of final which only requires definite assignment.
-     */
-    public abstract boolean isImmutable();
-
-    public final boolean isMutable() {
-        return !isImmutable();
-    }
-
-    public final boolean isAny() {
-        return this == ANY_LOCATION;
-    }
-
-    public final boolean isInit() {
-        return this == INIT_LOCATION;
-    }
-
-    public final boolean isSingle() {
-        return this != ANY_LOCATION;
-    }
-
-    public final boolean overlaps(LocationIdentity other) {
-        return isAny() || other.isAny() || this.equals(other);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/Pointer.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,965 +0,0 @@
-/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.word;
-
-/**
- * Lowest-level memory access of native C memory.
- * <p>
- * Do not use these methods to access Java objects. These methods access the raw memory without any
- * null checks, read- or write barriers. Even when the VM uses compressed pointers, then readObject
- * and writeObject methods access uncompressed pointers.
- */
-public interface Pointer extends UnsignedWord, PointerBase {
-
-    /**
-     * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type
-     * checks are performed. The caller must ensure that the Pointer contains a valid Java object
-     * that can i.e., processed by the garbage collector.
-     *
-     * @return this Pointer cast to Object.
-     */
-    Object toObject();
-
-    /**
-     * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type
-     * checks are performed. The caller must ensure that the Pointer contains a valid Java object
-     * that can i.e., processed by the garbage collector and the Pointer does not contain 0.
-     *
-     * @return this Pointer cast to non-null Object.
-     */
-    Object toObjectNonNull();
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    byte readByte(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    char readChar(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    short readShort(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    int readInt(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    long readLong(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    float readFloat(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    double readDouble(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    <T extends WordBase> T readWord(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    Object readObject(WordBase offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    byte readByte(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    char readChar(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    short readShort(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    int readInt(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    long readLong(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    float readFloat(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    double readDouble(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    <T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the read
-     * @return the result of the memory access
-     */
-    Object readObject(int offset, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeChar(WordBase offset, char val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeShort(WordBase offset, short val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeInt(WordBase offset, int val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeLong(WordBase offset, long val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity);
-
-    /**
-     * Initializes the memory at address {@code (this + offset)}. Both the base address and offset
-     * are in bytes. The memory must be uninitialized or zero prior to this operation.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeByte(int offset, byte val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeChar(int offset, char val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeShort(int offset, short val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeInt(int offset, int val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeLong(int offset, long val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeFloat(int offset, float val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeDouble(int offset, double val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeWord(int offset, WordBase val, LocationIdentity locationIdentity);
-
-    /**
-     * Initializes the memory at address {@code (this + offset)}. Both the base address and offset
-     * are in bytes. The memory must be uninitialized or zero prior to this operation.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void initializeLong(int offset, long val, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param locationIdentity the identity of the write
-     * @param val the value to be written to memory
-     */
-    void writeObject(int offset, Object val, LocationIdentity locationIdentity);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    byte readByte(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    char readChar(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    short readShort(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    int readInt(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    long readLong(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    float readFloat(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    double readDouble(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    <T extends WordBase> T readWord(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    Object readObject(WordBase offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    byte readByte(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    char readChar(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    short readShort(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    int readInt(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    long readLong(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    float readFloat(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    double readDouble(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    <T extends WordBase> T readWord(int offset);
-
-    /**
-     * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @return the result of the memory access
-     */
-    Object readObject(int offset);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeByte(WordBase offset, byte val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeChar(WordBase offset, char val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeShort(WordBase offset, short val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeInt(WordBase offset, int val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeLong(WordBase offset, long val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeFloat(WordBase offset, float val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeDouble(WordBase offset, double val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeWord(WordBase offset, WordBase val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     * <p>
-     * The offset is always treated as a {@link SignedWord} value. However, the static type is
-     * {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
-     * knows that the highest-order bit of the unsigned value is never used).
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeObject(WordBase offset, Object val);
-
-    int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
-
-    long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
-
-    <T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
-
-    Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeByte(int offset, byte val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeChar(int offset, char val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeShort(int offset, short val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeInt(int offset, int val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeLong(int offset, long val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeFloat(int offset, float val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeDouble(int offset, double val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeWord(int offset, WordBase val);
-
-    /**
-     * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
-     * bytes.
-     *
-     * @param offset the signed offset for the memory access
-     * @param val the value to be written to memory
-     */
-    void writeObject(int offset, Object val);
-
-    int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
-
-    long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
-
-    <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
-
-    Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
-
-    boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
-
-    // Math functions that are defined in Unsigned, but known to preserve the
-    // pointer-characteristics.
-    // It is therefore safe that they return a static type of Pointer instead of Unsigned.
-
-    @Override
-    Pointer add(UnsignedWord val);
-
-    @Override
-    Pointer add(int val);
-
-    @Override
-    Pointer subtract(UnsignedWord val);
-
-    @Override
-    Pointer subtract(int val);
-
-    @Override
-    Pointer and(UnsignedWord val);
-
-    @Override
-    Pointer and(int val);
-
-    @Override
-    Pointer or(UnsignedWord val);
-
-    @Override
-    Pointer or(int val);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/PointerBase.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 org.graalvm.word;
-
-/**
- * Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not
- * necessarily all the memory access methods defined in {@link Pointer}).
- */
-public interface PointerBase extends ComparableWord {
-
-    /**
-     * Returns true if this pointer is the {@link WordFactory#nullPointer null pointer}.
-     */
-    boolean isNull();
-
-    /**
-     * Returns true if this pointer is not the {@link WordFactory#nullPointer null pointer}.
-     */
-    boolean isNonNull();
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/SignedWord.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,298 +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.  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 org.graalvm.word;
-
-public interface SignedWord extends ComparableWord {
-
-    /**
-     * Returns a Signed whose value is {@code (this + val)}.
-     *
-     * @param val value to be added to this Signed.
-     * @return {@code this + val}
-     */
-    SignedWord add(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this - val)}.
-     *
-     * @param val value to be subtracted from this Signed.
-     * @return {@code this - val}
-     */
-    SignedWord subtract(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this * val)}.
-     *
-     * @param val value to be multiplied by this Signed.
-     * @return {@code this * val}
-     */
-    SignedWord multiply(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this / val)}.
-     *
-     * @param val value by which this Signed is to be divided.
-     * @return {@code this / val}
-     */
-    SignedWord signedDivide(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this % val)}.
-     *
-     * @param val value by which this Signed is to be divided, and the remainder computed.
-     * @return {@code this % val}
-     */
-    SignedWord signedRemainder(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this << n)}.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this << n}
-     */
-    SignedWord shiftLeft(UnsignedWord n);
-
-    /**
-     * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this >> n}
-     */
-    SignedWord signedShiftRight(UnsignedWord n);
-
-    /**
-     * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
-     * if and only if this and val are both negative.)
-     *
-     * @param val value to be AND'ed with this Signed.
-     * @return {@code this & val}
-     */
-    SignedWord and(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
-     * if and only if either this or val is negative.)
-     *
-     * @param val value to be OR'ed with this Signed.
-     * @return {@code this | val}
-     */
-    SignedWord or(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
-     * if and only if exactly one of this and val are negative.)
-     *
-     * @param val value to be XOR'ed with this Signed.
-     * @return {@code this ^ val}
-     */
-    SignedWord xor(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (~this)}. (This method returns a negative value if and
-     * only if this Signed is non-negative.)
-     *
-     * @return {@code ~this}
-     */
-    SignedWord not();
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this == val}
-     */
-    boolean equal(SignedWord val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this != val}
-     */
-    boolean notEqual(SignedWord val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this < val}
-     */
-    boolean lessThan(SignedWord val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this <= val}
-     */
-    boolean lessOrEqual(SignedWord val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this > val}
-     */
-    boolean greaterThan(SignedWord val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this >= val}
-     */
-    boolean greaterOrEqual(SignedWord val);
-
-    /**
-     * Returns a Signed whose value is {@code (this + val)}.
-     *
-     * @param val value to be added to this Signed.
-     * @return {@code this + val}
-     */
-    SignedWord add(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this - val)}.
-     *
-     * @param val value to be subtracted from this Signed.
-     * @return {@code this - val}
-     */
-    SignedWord subtract(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this * val)}.
-     *
-     * @param val value to be multiplied by this Signed.
-     * @return {@code this * val}
-     */
-    SignedWord multiply(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this / val)}.
-     *
-     * @param val value by which this Signed is to be divided.
-     * @return {@code this / val}
-     */
-    SignedWord signedDivide(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this % val)}.
-     *
-     * @param val value by which this Signed is to be divided, and the remainder computed.
-     * @return {@code this % val}
-     */
-    SignedWord signedRemainder(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this << n)}.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this << n}
-     */
-    SignedWord shiftLeft(int n);
-
-    /**
-     * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this >> n}
-     */
-    SignedWord signedShiftRight(int n);
-
-    /**
-     * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
-     * if and only if this and val are both negative.)
-     *
-     * @param val value to be AND'ed with this Signed.
-     * @return {@code this & val}
-     */
-    SignedWord and(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
-     * if and only if either this or val is negative.)
-     *
-     * @param val value to be OR'ed with this Signed.
-     * @return {@code this | val}
-     */
-    SignedWord or(int val);
-
-    /**
-     * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
-     * if and only if exactly one of this and val are negative.)
-     *
-     * @param val value to be XOR'ed with this Signed.
-     * @return {@code this ^ val}
-     */
-    SignedWord xor(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this == val}
-     */
-    boolean equal(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this != val}
-     */
-    boolean notEqual(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this < val}
-     */
-    boolean lessThan(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this <= val}
-     */
-    boolean lessOrEqual(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this > val}
-     */
-    boolean greaterThan(int val);
-
-    /**
-     * Compares this Signed with the specified value.
-     *
-     * @param val value to which this Signed is to be compared.
-     * @return {@code this >= val}
-     */
-    boolean greaterOrEqual(int val);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/UnsignedWord.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +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.  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 org.graalvm.word;
-
-public interface UnsignedWord extends ComparableWord {
-
-    /**
-     * Returns a Unsigned whose value is {@code (this + val)}.
-     *
-     * @param val value to be added to this Unsigned.
-     * @return {@code this + val}
-     */
-    UnsignedWord add(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this - val)}.
-     *
-     * @param val value to be subtracted from this Unsigned.
-     * @return {@code this - val}
-     */
-    UnsignedWord subtract(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this * val)}.
-     *
-     * @param val value to be multiplied by this Unsigned.
-     * @return {@code this * val}
-     */
-    UnsignedWord multiply(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this / val)}.
-     *
-     * @param val value by which this Unsigned is to be divided.
-     * @return {@code this / val}
-     */
-    UnsignedWord unsignedDivide(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this % val)}.
-     *
-     * @param val value by which this Unsigned is to be divided, and the remainder computed.
-     * @return {@code this % val}
-     */
-    UnsignedWord unsignedRemainder(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this << n)}.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this << n}
-     */
-    UnsignedWord shiftLeft(UnsignedWord n);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this >> n}
-     */
-    UnsignedWord unsignedShiftRight(UnsignedWord n);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this & val)}.
-     *
-     * @param val value to be AND'ed with this Unsigned.
-     * @return {@code this & val}
-     */
-    UnsignedWord and(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this | val)}.
-     *
-     * @param val value to be OR'ed with this Unsigned.
-     * @return {@code this | val}
-     */
-    UnsignedWord or(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this ^ val)}.
-     *
-     * @param val value to be XOR'ed with this Unsigned.
-     * @return {@code this ^ val}
-     */
-    UnsignedWord xor(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (~this)}.
-     *
-     * @return {@code ~this}
-     */
-    UnsignedWord not();
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this == val}
-     */
-    boolean equal(UnsignedWord val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this != val}
-     */
-    boolean notEqual(UnsignedWord val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this < val}
-     */
-    boolean belowThan(UnsignedWord val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this <= val}
-     */
-    boolean belowOrEqual(UnsignedWord val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this > val}
-     */
-    boolean aboveThan(UnsignedWord val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this >= val}
-     */
-    boolean aboveOrEqual(UnsignedWord val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this + val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be added to this Unsigned.
-     * @return {@code this + val}
-     */
-    UnsignedWord add(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this - val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be subtracted from this Unsigned.
-     * @return {@code this - val}
-     */
-    UnsignedWord subtract(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this * val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be multiplied by this Unsigned.
-     * @return {@code this * val}
-     */
-    UnsignedWord multiply(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this / val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value by which this Unsigned is to be divided.
-     * @return {@code this / val}
-     */
-    UnsignedWord unsignedDivide(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this % val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value by which this Unsigned is to be divided, and the remainder computed.
-     * @return {@code this % val}
-     */
-    UnsignedWord unsignedRemainder(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this << n)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this << n}
-     */
-    UnsignedWord shiftLeft(int n);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param n shift distance, in bits.
-     * @return {@code this >> n}
-     */
-    UnsignedWord unsignedShiftRight(int n);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this & val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be AND'ed with this Unsigned.
-     * @return {@code this & val}
-     */
-    UnsignedWord and(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this | val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be OR'ed with this Unsigned.
-     * @return {@code this | val}
-     */
-    UnsignedWord or(int val);
-
-    /**
-     * Returns a Unsigned whose value is {@code (this ^ val)}.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to be XOR'ed with this Unsigned.
-     * @return {@code this ^ val}
-     */
-    UnsignedWord xor(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this == val}
-     */
-    boolean equal(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this != val}
-     */
-    boolean notEqual(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this < val}
-     */
-    boolean belowThan(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this <= val}
-     */
-    boolean belowOrEqual(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this > val}
-     */
-    boolean aboveThan(int val);
-
-    /**
-     * Compares this Unsigned with the specified value.
-     * <p>
-     * Note that the right operand is a signed value, while the operation is performed unsigned.
-     * Therefore, the result is only well-defined for positive right operands.
-     *
-     * @param val value to which this Unsigned is to be compared.
-     * @return {@code this >= val}
-     */
-    boolean aboveOrEqual(int val);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/WordBase.java	Tue Apr 24 08:13:30 2018 -0700
+++ /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.  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 org.graalvm.word;
-
-public interface WordBase {
-
-    long rawValue();
-
-    /**
-     * This is deprecated because of the easy to mistype name collision between {@link #equals} and
-     * the other word based equality routines. In general you should never be statically calling
-     * this method anyway.
-     */
-    @Override
-    @Deprecated
-    boolean equals(Object o);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/src/org/graalvm/word/WordFactory.java	Tue Apr 24 08:13:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 org.graalvm.word;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-public abstract class WordFactory {
-
-    /**
-     * Links a method to a canonical operation represented by an {@link FactoryOpcode} val.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    protected @interface FactoryOperation {
-        FactoryOpcode opcode();
-    }
-
-    /**
-     * The canonical {@link FactoryOperation} represented by a method in a word type.
-     */
-    protected enum FactoryOpcode {
-        ZERO,
-        FROM_UNSIGNED,
-        FROM_SIGNED,
-    }
-
-    protected interface BoxFactory {
-        <T extends WordBase> T box(long val);
-    }
-
-    protected static BoxFactory boxFactory;
-
-    /**
-     * We allow subclassing, because only subclasses can access the protected inner classes that we
-     * use to mark the operations.
-     */
-    protected WordFactory() {
-    }
-
-    /**
-     * The constant 0, i.e., the word with no bits set. There is no difference between a signed and
-     * unsigned zero.
-     *
-     * @return the constant 0.
-     */
-    @FactoryOperation(opcode = FactoryOpcode.ZERO)
-    public static <T extends WordBase> T zero() {
-        return boxFactory.box(0L);
-    }
-
-    /**
-     * The null pointer, i.e., the pointer with no bits set. There is no difference to a signed or
-     * unsigned {@link #zero}.
-     *
-     * @return the null pointer.
-     */
-    @FactoryOperation(opcode = FactoryOpcode.ZERO)
-    public static <T extends PointerBase> T nullPointer() {
-        return boxFactory.box(0L);
-    }
-
-    /**
-     * Unsafe conversion from a Java long value to a Word. The parameter is treated as an unsigned
-     * 64-bit value (in contrast to the semantics of a Java long).
-     *
-     * @param val a 64 bit unsigned value
-     * @return the value cast to Word
-     */
-    @FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
-    public static <T extends UnsignedWord> T unsigned(long val) {
-        return boxFactory.box(val);
-    }
-
-    /**
-     * Unsafe conversion from a Java long value to a {@link PointerBase pointer}. The parameter is
-     * treated as an unsigned 64-bit value (in contrast to the semantics of a Java long).
-     *
-     * @param val a 64 bit unsigned value
-     * @return the value cast to PointerBase
-     */
-    @FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
-    public static <T extends PointerBase> T pointer(long val) {
-        return boxFactory.box(val);
-    }
-
-    /**
-     * Unsafe conversion from a Java int value to a Word. The parameter is treated as an unsigned
-     * 32-bit value (in contrast to the semantics of a Java int).
-     *
-     * @param val a 32 bit unsigned value
-     * @return the value cast to Word
-     */
-    @FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
-    public static <T extends UnsignedWord> T unsigned(int val) {
-        return boxFactory.box(val & 0xffffffffL);
-    }
-
-    /**
-     * Unsafe conversion from a Java long value to a Word. The parameter is treated as a signed
-     * 64-bit value (unchanged semantics of a Java long).
-     *
-     * @param val a 64 bit signed value
-     * @return the value cast to Word
-     */
-    @FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
-    public static <T extends SignedWord> T signed(long val) {
-        return boxFactory.box(val);
-    }
-
-    /**
-     * Unsafe conversion from a Java int value to a Word. The parameter is treated as a signed
-     * 32-bit value (unchanged semantics of a Java int).
-     *
-     * @param val a 32 bit signed value
-     * @return the value cast to Word
-     */
-    @FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
-    public static <T extends SignedWord> T signed(int val) {
-        return boxFactory.box(val);
-    }
-}