changeset 48861:47f19ff9903c

8194819: Update Graal Reviewed-by: kvn
author iveresov
date Fri, 02 Feb 2018 17:28:17 -0800
parents 5bce1b7e7800
children e13c8c5d9eb3
files make/CompileJavaModules.gmk make/CompileToolsHotspot.gmk src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java src/jdk.internal.vm.compiler/.mx.graal/suite.py 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.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives/src/org/graalvm/compiler/api/directives/GraalDirectives.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitution.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/SnippetReflectionProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/GraalRuntime.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.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/DataSection.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64CompressAddressLowering.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.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.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/TraceInliningMode.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/calc/CanonicalCondition.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ArrayOffsetProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.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.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc.test/src/org/graalvm/compiler/core/sparc/test/SPARCAllocatorTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest11.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.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/GraalCompilerTest.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/GraphScheduleTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.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/SchedulingTest2.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.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/GraalCompiler.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/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/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/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/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/TimerKeyImpl.java 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/NodeBitMap.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/NodeStack.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.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/ArrayAccessInLoopToAddressTest.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/AMD64HotSpotLIRGenerator.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc.test/src/org/graalvm/compiler/core/sparc/test/SPARCAllocatorTest.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.test/src/org/graalvm/compiler/hotspot/test/ArrayNewInstanceTest.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/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/HotSpotGraalMBeanTest.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/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/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/HotSpotDataBuilder.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/HotSpotGraalMBean.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/HotSpotLIRGenerationResult.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/HotSpotSnippetReflectionProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ArrayRangeWriteBarrier.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.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/WriteBarrierVerificationPhase.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/ClassGetHubNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotArraySubstitutions.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/NewObjectSnippets.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/ArrayCopySnippets.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.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.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayEqualsOp.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Call.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.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/SPARCArrayEqualsOp.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/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/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/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/PreAllocationOptimizationStage.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.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.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.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/SchedulePhaseBenchmark.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/util/ScheduleState.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IfNodeCanonicalizationTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ControlSplitNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/DeoptimizeNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/DeoptimizingGuard.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedGuardNode.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/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/NamedLocationIdentity.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StaticDeoptimizingNode.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/calc/CompareNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConvertNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.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/extended/ArrayRangeWrite.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWriteNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.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/SwitchNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.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/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/DynamicNewArrayNode.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/NewArrayNode.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/spi/LoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.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/VirtualArrayNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualObjectNode.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/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/OptionsParser.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.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/ConvertDeoptimizeToGuardPhase.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/GuardLoweringPhase.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/UseTrappingNullChecksPhase.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/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/util/GraphOrder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.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/CFGPrinter.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/FoldTest.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/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.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/InstanceOfSnippetsTemplates.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/NodeIntrinsificationProvider.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/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/Classfile.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/ClassfileConstant.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileConstantPool.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider.processor/src/org/graalvm/compiler/serviceprovider/processor/ServiceProviderProcessor.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/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.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.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.graphio/src/org/graalvm/graphio/GraphJavadocSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionCategory.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptor.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptors.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionKey.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionType.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionValues.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/package-info.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.test/src/org/graalvm/util/test/CollectionTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionUtilTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/CollectionsUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/EconomicMap.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/EconomicSet.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/Equivalence.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/MapCursor.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.util/src/org/graalvm/util/Pair.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/UnmodifiableEconomicMap.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/UnmodifiableEconomicSet.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/UnmodifiableMapCursor.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/impl/EconomicMapImpl.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml
diffstat 313 files changed, 6691 insertions(+), 4786 deletions(-) [+]
line wrap: on
line diff
--- a/make/CompileJavaModules.gmk	Fri Feb 02 10:37:48 2018 -0500
+++ b/make/CompileJavaModules.gmk	Fri Feb 02 17:28:17 2018 -0800
@@ -493,6 +493,7 @@
     #
 
 jdk.internal.vm.compiler_EXCLUDES += \
+    org.graalvm.collections.test \
     org.graalvm.compiler.core.match.processor \
     org.graalvm.compiler.nodeinfo.processor \
     org.graalvm.compiler.options.processor \
@@ -511,6 +512,7 @@
     org.graalvm.compiler.graph.test \
     org.graalvm.compiler.hotspot.amd64.test \
     org.graalvm.compiler.hotspot.lir.test \
+    org.graalvm.compiler.hotspot.sparc.test \
     org.graalvm.compiler.hotspot.test \
     org.graalvm.compiler.jtt \
     org.graalvm.compiler.lir.jtt \
--- a/make/CompileToolsHotspot.gmk	Fri Feb 02 10:37:48 2018 -0500
+++ b/make/CompileToolsHotspot.gmk	Fri Feb 02 17:28:17 2018 -0800
@@ -48,6 +48,7 @@
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
           $(SRC_DIR)/org.graalvm.word/src \
+          $(SRC_DIR)/org.graalvm.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 \
@@ -101,6 +102,7 @@
   $(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
+          $(SRC_DIR)/org.graalvm.collections/src \
           $(SRC_DIR)/org.graalvm.compiler.options/src \
           $(SRC_DIR)/org.graalvm.compiler.options.processor/src \
           $(SRC_DIR)/org.graalvm.util/src \
@@ -117,6 +119,7 @@
       SETUP := GENERATE_OLDBYTECODE, \
       SRC := \
           $(SRC_DIR)/org.graalvm.word/src \
+          $(SRC_DIR)/org.graalvm.collections/src \
           $(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
           $(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
           $(SRC_DIR)/org.graalvm.compiler.code/src \
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java	Fri Feb 02 17:28:17 2018 -0800
@@ -143,7 +143,7 @@
         int alignment = data.getAlignment();
         byte[] value = new byte[size];
         ByteBuffer buffer = ByteBuffer.wrap(value).order(ByteOrder.nativeOrder());
-        DataSection.emit(buffer, data, p -> {
+        DataSection.emit(buffer, data, (p, c) -> {
         });
         String targetSymbol = "data.M" + methodInfo.getCodeId() + "." + dataOffset;
         Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol);
--- a/src/jdk.internal.vm.compiler/.mx.graal/suite.py	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/.mx.graal/suite.py	Fri Feb 02 17:28:17 2018 -0800
@@ -82,6 +82,24 @@
       "javaCompliance" : "1.8",
       "workingSets" : "API,SDK",
     },
+    "org.graalvm.collections" : {
+      "subDir" : "share/classes",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "org.graalvm.word",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,SDK",
+    },
+    "org.graalvm.collections.test" : {
+      "subDir" : "share/classes",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "mx:JUNIT",
+        "org.graalvm.collections",
+      ],
+      "checkstyle" : "org.graalvm.word",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,SDK,Test",
+    },
 
     # ------------- Graal -------------
 
@@ -190,6 +208,9 @@
     "org.graalvm.util" : {
       "subDir" : "share/classes",
       "sourceDirs" : ["src"],
+      "dependencies" : [
+        "org.graalvm.collections",
+      ],
       "checkstyle" : "org.graalvm.compiler.graph",
       "javaCompliance" : "1.8",
       "workingSets" : "API,Graal",
@@ -201,6 +222,7 @@
       "dependencies" : [
         "mx:JUNIT",
         "org.graalvm.util",
+        "org.graalvm.compiler.core.test",
       ],
       "checkstyle" : "org.graalvm.compiler.graph",
       "javaCompliance" : "1.8",
@@ -970,10 +992,11 @@
       "workingSets" : "Graal,SPARC",
     },
 
-    "org.graalvm.compiler.core.sparc.test" : {
+    "org.graalvm.compiler.hotspot.sparc.test" : {
       "subDir" : "share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
+        "org.graalvm.compiler.hotspot",
         "org.graalvm.compiler.lir.jtt",
         "JVMCI_HOTSPOT"
       ],
@@ -1007,6 +1030,7 @@
       "subDir" : "share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
+        "org.graalvm.collections",
         "org.graalvm.compiler.debug",
         "org.graalvm.word",
       ],
@@ -1037,7 +1061,6 @@
       "sourceDirs" : ["src"],
       "dependencies" : [
         "org.graalvm.compiler.debug",
-        "org.graalvm.util",
         "mx:JUNIT",
       ],
       "checkstyle" : "org.graalvm.compiler.graph",
@@ -1225,11 +1248,11 @@
         "org.graalvm.compiler.asm.amd64.test",
         "org.graalvm.compiler.core.aarch64.test",
         "org.graalvm.compiler.core.amd64.test",
-        "org.graalvm.compiler.core.sparc.test",
         "org.graalvm.compiler.debug.test",
         "org.graalvm.compiler.hotspot.aarch64.test",
         "org.graalvm.compiler.hotspot.amd64.test",
         "org.graalvm.compiler.hotspot.lir.test",
+        "org.graalvm.compiler.hotspot.sparc.test",
         "org.graalvm.compiler.options.test",
         "org.graalvm.compiler.jtt",
         "org.graalvm.compiler.lir.jtt",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapImplTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapLargeTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicMapTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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)})");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EconomicSetTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/EquivalenceTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections.test/src/org/graalvm/collections/test/PairTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMap.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicMapImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/EconomicSet.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Equivalence.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/MapCursor.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/Pair.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicMap.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableEconomicSet.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/UnmodifiableMapCursor.java	Fri Feb 02 17:28:17 2018 -0800
@@ -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 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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.collections/src/org/graalvm/collections/package-info.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -50,6 +50,21 @@
         test("branchProbabilitySnippet", 5);
     }
 
+    public static int branchProbabilitySnippet2(int arg) {
+        if (!GraalDirectives.injectBranchProbability(0.125, arg <= 0)) {
+            GraalDirectives.controlFlowAnchor(); // prevent removal of the if
+            return 2;
+        } else {
+            GraalDirectives.controlFlowAnchor(); // prevent removal of the if
+            return 1;
+        }
+    }
+
+    @Test
+    public void testBranchProbability2() {
+        test("branchProbabilitySnippet2", 5);
+    }
+
     @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives/src/org/graalvm/compiler/api/directives/GraalDirectives.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives/src/org/graalvm/compiler/api/directives/GraalDirectives.java	Fri Feb 02 17:28:17 2018 -0800
@@ -50,6 +50,13 @@
     }
 
     /**
+     * Directive for the compiler to fall back to the bytecode interpreter at this point, invalidate
+     * the compiled code, record a speculation and reprofile the method.
+     */
+    public static void deoptimizeAndInvalidateWithSpeculation() {
+    }
+
+    /**
      * Returns a boolean value indicating whether the method is executed in Graal-compiled code.
      */
     public static boolean inCompiledCode() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitution.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitution.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,15 +26,52 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.lang.reflect.Array;
 
 import jdk.vm.ci.meta.Signature;
 
 /**
  * Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of
- * another method. The exact method used to do the substitution is compiler dependent but every
+ * another method. The exact mechanism used to do the substitution is compiler dependent but every
  * compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In
  * addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
  * the mechanism by which it supports registration of method substitutes.
+ *
+ * A compiler may support partial intrinsification where only a part of a method is implemented by
+ * the compiler. The unsupported path is expressed by a call to either the original or substitute
+ * method from within the substitute method. Such as call is a <i>partial intrinsic exit</i>.
+ *
+ * For example, here's a HotSpot specific intrinsic for {@link Array#newInstance(Class, int)} that
+ * only handles the case where the VM representation of the array class to be instantiated already
+ * exists:
+ *
+ * <pre>
+ * &#64;MethodSubstitution
+ * public static Object newInstance(Class<?> componentType, int length) {
+ *     if (componentType == null || loadKlassFromObject(componentType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION).isNull()) {
+ *         // Array class not yet created - exit the intrinsic and call the original method
+ *         return newInstance(componentType, length);
+ *     }
+ *     return DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(componentType), length, JavaKind.Object);
+ * }
+ * </pre>
+ *
+ * Here's the same intrinsification where the exit is expressed as a call to the original method:
+ *
+ * <pre>
+ * &#64;MethodSubstitution
+ * public static Object newInstance(Class<?> componentType, int length) {
+ *     if (componentType == null || loadKlassFromObject(componentType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION).isNull()) {
+ *         // Array class not yet created - exit the intrinsic and call the original method
+ *         return java.lang.reflect.newInstance(componentType, length);
+ *     }
+ *     return DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(componentType), length, JavaKind.Object);
+ * }
+ * </pre>
+ *
+ * A condition for a partial intrinsic exit is that it is uses the unmodified parameters of the
+ * substitute as arguments to the partial intrinsic exit call. There must also be no side effecting
+ * instruction between the start of the substitute method and the partial intrinsic exit.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/SnippetReflectionProvider.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/SnippetReflectionProvider.java	Fri Feb 02 17:28:17 2018 -0800
@@ -90,4 +90,12 @@
      *         if this provider cannot provide a value of the requested type
      */
     <T> T getInjectedNodeIntrinsicParameter(Class<T> type);
+
+    /**
+     * Get the original Java class corresponding to a {@link ResolvedJavaType}.
+     *
+     * @param type the type for which the original Java class is requested
+     * @return the original Java class corresponding to the {@code type} parameter
+     */
+    Class<?> originalClass(ResolvedJavaType type);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/GraalRuntime.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/GraalRuntime.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,9 +22,19 @@
  */
 package org.graalvm.compiler.api.runtime;
 
+import jdk.vm.ci.common.JVMCIError;
+
 public interface GraalRuntime {
 
     String getName();
 
     <T> T getCapability(Class<T> clazz);
+
+    default <T> T getRequiredCapability(Class<T> clazz) {
+        T ret = getCapability(clazz);
+        if (ret == null) {
+            throw new JVMCIError("The VM does not expose the required Graal capability %s.", clazz.getName());
+        }
+        return ret;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Feb 02 17:28:17 2018 -0800
@@ -208,7 +208,6 @@
     }
 
     private static class VexOpcode {
-        private static final int VEX_OPCODE_NONE = 0x0;
         private static final int VEX_OPCODE_0F = 0x1;
         private static final int VEX_OPCODE_0F_38 = 0x2;
         private static final int VEX_OPCODE_0F_3A = 0x3;
@@ -861,9 +860,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 boolean rexVexW = (size == QWORD) ? true : false;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
@@ -881,20 +897,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
                 int encode;
                 if (noNds) {
                     encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
@@ -938,9 +940,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 boolean rexVexW = (size == QWORD) ? true : false;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
@@ -958,20 +977,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
                 if (noNds) {
                     asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
                 } else {
@@ -1055,8 +1060,7 @@
                     opc = VexOpcode.VEX_OPCODE_0F_3A;
                     break;
                 default:
-                    opc = VexOpcode.VEX_OPCODE_NONE;
-                    break;
+                    throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
             }
             int encode;
             encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes);
@@ -1096,8 +1100,7 @@
                     opc = VexOpcode.VEX_OPCODE_0F_3A;
                     break;
                 default:
-                    opc = VexOpcode.VEX_OPCODE_NONE;
-                    break;
+                    throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
             }
             asm.simdPrefix(dst, nds, src, pre, opc, attributes);
             asm.emitByte(op);
@@ -1163,9 +1166,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 boolean rexVexW = (size == QWORD) ? true : false;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
@@ -1183,20 +1203,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
                 int encode;
                 if (noNds) {
                     encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes);
@@ -1222,9 +1228,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 boolean rexVexW = (size == QWORD) ? true : false;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
@@ -1242,20 +1265,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
                 asm.simdPrefix(src, Register.None, dst, pre, opc, attributes);
                 asm.emitByte(op);
                 asm.emitOperandHelper(src, dst, 0);
@@ -1390,9 +1399,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
                 switch (curPrefix) {
@@ -1409,20 +1435,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
                 int encode;
                 if (noNds) {
                     encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
@@ -1453,9 +1465,26 @@
                     break;
             }
 
+            int opc = 0;
+            if (isSimd) {
+                switch (prefix2) {
+                    case P_0F:
+                        opc = VexOpcode.VEX_OPCODE_0F;
+                        break;
+                    case P_0F38:
+                        opc = VexOpcode.VEX_OPCODE_0F_38;
+                        break;
+                    case P_0F3A:
+                        opc = VexOpcode.VEX_OPCODE_0F_3A;
+                        break;
+                    default:
+                        isSimd = false;
+                        break;
+                }
+            }
+
             if (isSimd) {
                 int pre;
-                int opc;
                 AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
                 int curPrefix = size.sizePrefix | prefix1;
                 switch (curPrefix) {
@@ -1472,21 +1501,6 @@
                         pre = VexSimdPrefix.VEX_SIMD_NONE;
                         break;
                 }
-                switch (prefix2) {
-                    case P_0F:
-                        opc = VexOpcode.VEX_OPCODE_0F;
-                        break;
-                    case P_0F38:
-                        opc = VexOpcode.VEX_OPCODE_0F_38;
-                        break;
-                    case P_0F3A:
-                        opc = VexOpcode.VEX_OPCODE_0F_3A;
-                        break;
-                    default:
-                        opc = VexOpcode.VEX_OPCODE_NONE;
-                        break;
-                }
-
                 if (noNds) {
                     asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
                 } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java	Fri Feb 02 17:28:17 2018 -0800
@@ -33,9 +33,9 @@
 import java.util.List;
 import java.util.Objects;
 
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.graph.NodeSourcePosition;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.code.DebugInfo;
 import jdk.vm.ci.code.StackSlot;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java	Fri Feb 02 17:28:17 2018 -0800
@@ -40,7 +40,7 @@
 
     public interface Patches {
 
-        void registerPatch(VMConstant c);
+        void registerPatch(int position, VMConstant c);
     }
 
     public abstract static class Data {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Fri Feb 02 17:28:17 2018 -0800
@@ -27,7 +27,6 @@
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
-import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -107,7 +106,9 @@
                 ret.setBase(add.getX());
                 ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
                 return true;
-            } else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
+            }
+
+            if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
                 AddNode add = (AddNode) ret.getIndex();
                 ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
                 ret.setIndex(add.getY());
@@ -188,7 +189,7 @@
             return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
         } else {
             if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
-                assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
+                assert IntegerStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
 
                 /*
                  * we can't swallow zero-extends because of multiple reasons:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64CompressAddressLowering.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,98 @@
+/*
+ * 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.core.amd64;
+
+import jdk.vm.ci.code.Register;
+import org.graalvm.compiler.asm.amd64.AMD64Address;
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.debug.CounterKey;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.CompressionNode;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.spi.LIRLowerable;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
+
+public abstract class AMD64CompressAddressLowering extends AMD64AddressLowering {
+    private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering");
+
+    @Override
+    protected final boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
+        if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
+            return true;
+        }
+
+        if (!isBaseNegated && !isIndexNegated && addr.getScale() == AMD64Address.Scale.Times1) {
+            ValueNode base = addr.getBase();
+            ValueNode index = addr.getIndex();
+
+            if (tryToImproveUncompression(addr, index, base) || tryToImproveUncompression(addr, base, index)) {
+                counterFoldedUncompressDuringAddressLowering.increment(debug);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private boolean tryToImproveUncompression(AMD64AddressNode addr, ValueNode value, ValueNode other) {
+        if (value instanceof CompressionNode) {
+            CompressionNode compression = (CompressionNode) value;
+            if (compression.getOp() == CompressionNode.CompressionOp.Uncompress && improveUncompression(addr, compression, other)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected abstract boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other);
+
+    @NodeInfo(cycles = CYCLES_0, size = SIZE_0)
+    public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
+
+        public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
+
+        private final Register heapBaseRegister;
+
+        public HeapBaseNode(Register heapBaseRegister) {
+            super(TYPE, StampFactory.pointer());
+            this.heapBaseRegister = heapBaseRegister;
+        }
+
+        @Override
+        public void generate(NodeLIRBuilderTool generator) {
+            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
+            generator.setResult(this, heapBaseRegister.asValue(kind));
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,14 +26,14 @@
 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 org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.lir.VirtualStackSlot;
 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
 import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove;
 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.code.Architecture;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Fri Feb 02 17:28:17 2018 -0800
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
 import org.graalvm.compiler.core.gen.NodeMatchRules;
@@ -128,7 +129,7 @@
     }
 
     protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
-        Condition cond = compare.condition();
+        Condition cond = compare.condition().asCondition();
         AMD64Kind kind = getMemoryKind(access);
         boolean matchedAsConstant = false; // For assertion checking
 
@@ -303,7 +304,7 @@
     @MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))")
     @MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))")
     public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) {
-        assert compare.condition() == Condition.EQ;
+        assert compare.condition() == CanonicalCondition.EQ;
         if (value == cas.getExpectedValue() && cas.usages().count() == 1) {
             return builder -> {
                 LIRKind kind = getLirKind(cas);
@@ -326,7 +327,7 @@
     @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
     public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
         JavaConstant constant = value.asJavaConstant();
-        assert compare.condition() == Condition.EQ;
+        assert compare.condition() == CanonicalCondition.EQ;
         if (constant != null && cas.usages().count() == 1) {
             long constantValue = constant.asLong();
             boolean successIsTrue;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Fri Feb 02 17:28:17 2018 -0800
@@ -233,6 +233,9 @@
     public static final OptionKey<Boolean> OptScheduleOutOfLoops = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
+    public static final OptionKey<Boolean> GuardPriorities = new OptionKey<>(true);
+
+    @Option(help = "", type = OptionType.Debug)
     public static final OptionKey<Boolean> OptEliminateGuards = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
@@ -271,4 +274,7 @@
     @Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
     public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
 
+    @Option(help = "How to trace inlining decisions, one of: None, Linear, Tree", type = OptionType.Debug)
+    public static final OptionKey<TraceInliningMode> TraceInlining = new OptionKey<>(TraceInliningMode.None);
+
 }
--- /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/TraceInliningMode.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,39 @@
+/*
+ * 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.core.common;
+
+public enum TraceInliningMode {
+    None(false),
+    Linear(true),
+    Tree(true);
+
+    private final boolean tracing;
+
+    TraceInliningMode(boolean tracing) {
+        this.tracing = tracing;
+    }
+
+    public boolean isTracing() {
+        return tracing;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/RegisterAllocationConfig.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/RegisterAllocationConfig.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,9 +22,9 @@
  */
 package org.graalvm.compiler.core.common.alloc;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.core.common.GraalOptions;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.Register.RegisterCategory;
--- /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/calc/CanonicalCondition.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 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.common.calc;
+
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.PrimitiveConstant;
+
+public enum CanonicalCondition {
+    EQ(Condition.EQ),
+    LT(Condition.LT),
+    BT(Condition.BT);
+
+    private final Condition condition;
+
+    CanonicalCondition(Condition condition) {
+        assert condition.isCanonical();
+        this.condition = condition;
+    }
+
+    public Condition asCondition() {
+        return condition;
+    }
+
+    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) {
+        return asCondition().foldCondition(lt, rt, constantReflection, unorderedIsTrue);
+    }
+
+    public boolean foldCondition(PrimitiveConstant lp, PrimitiveConstant rp, boolean unorderedIsTrue) {
+        return asCondition().foldCondition(lp, rp, unorderedIsTrue);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java	Fri Feb 02 17:28:17 2018 -0800
@@ -115,6 +115,55 @@
         throw new IllegalArgumentException(this.toString());
     }
 
+    public static final class CanonicalizedCondition {
+        private final CanonicalCondition canonicalCondition;
+        private final boolean mirror;
+        private final boolean negate;
+
+        private CanonicalizedCondition(CanonicalCondition canonicalCondition, boolean mirror, boolean negate) {
+            this.canonicalCondition = canonicalCondition;
+            this.mirror = mirror;
+            this.negate = negate;
+        }
+
+        public CanonicalCondition getCanonicalCondition() {
+            return canonicalCondition;
+        }
+
+        public boolean mustMirror() {
+            return mirror;
+        }
+
+        public boolean mustNegate() {
+            return negate;
+        }
+    }
+
+    public CanonicalizedCondition canonicalize() {
+        CanonicalCondition canonicalCondition;
+        switch (this) {
+            case EQ:
+            case NE:
+                canonicalCondition = CanonicalCondition.EQ;
+                break;
+            case LT:
+            case LE:
+            case GT:
+            case GE:
+                canonicalCondition = CanonicalCondition.LT;
+                break;
+            case BT:
+            case BE:
+            case AT:
+            case AE:
+                canonicalCondition = CanonicalCondition.BT;
+                break;
+            default:
+                throw new IllegalArgumentException(this.toString());
+        }
+        return new CanonicalizedCondition(canonicalCondition, canonicalMirror(), canonicalNegate());
+    }
+
     /**
      * Given a condition and its negation, this method returns true for one of the two and false for
      * the other one. This can be used to keep comparisons in a canonical form.
@@ -151,7 +200,7 @@
      * Returns true if the condition needs to be mirrored to get to a canonical condition. The
      * result of the mirroring operation might still need to be negated to achieve a canonical form.
      */
-    public boolean canonicalMirror() {
+    private boolean canonicalMirror() {
         switch (this) {
             case EQ:
                 return false;
@@ -181,7 +230,7 @@
      * Returns true if the condition needs to be negated to get to a canonical condition. The result
      * of the negation might still need to be mirrored to achieve a canonical form.
      */
-    public boolean canonicalNegate() {
+    private boolean canonicalNegate() {
         switch (this) {
             case EQ:
                 return false;
--- /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/spi/ArrayOffsetProvider.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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.core.common.spi;
+
+import jdk.vm.ci.meta.JavaKind;
+
+public interface ArrayOffsetProvider {
+
+    int arrayBaseOffset(JavaKind elementKind);
+
+    int arrayScalingFactor(JavaKind elementKind);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java	Fri Feb 02 17:28:17 2018 -0800
@@ -40,4 +40,5 @@
 
     ConstantReflectionProvider getConstantReflection();
 
+    ArrayOffsetProvider getArrayOffsetProvider();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,6 +28,9 @@
 import java.util.Objects;
 import java.util.function.Function;
 
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaKind;
+
 import org.graalvm.compiler.core.common.calc.FloatConvert;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
@@ -51,9 +54,6 @@
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
 import org.graalvm.util.CollectionsUtil;
 
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.JavaKind;
-
 /**
  * Information about arithmetic operations.
  */
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/FrequencyEncoder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/FrequencyEncoder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,8 +25,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.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.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java	Fri Feb 02 17:28:17 2018 -0800
@@ -58,6 +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 org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.core.match.ComplexMatchResult;
 import org.graalvm.compiler.core.match.MatchRule;
@@ -70,9 +73,6 @@
 import org.graalvm.compiler.graph.Position;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.EconomicSet;
 
 /**
  * Processes classes annotated with {@link MatchRule}. A {@link MatchStatementSet} service is
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc.test/src/org/graalvm/compiler/core/sparc/test/SPARCAllocatorTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.core.sparc.test;
-
-import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure;
-import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
-import static org.junit.Assume.assumeTrue;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.graalvm.compiler.core.test.backend.AllocatorTest;
-
-import jdk.vm.ci.sparc.SPARC;
-
-public class SPARCAllocatorTest extends AllocatorTest {
-
-    @Before
-    public void checkSPARC() {
-        assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
-        assumeTrue("RegisterPressure is set -> skip", RegisterPressure.getValue(getInitialOptions()) == null);
-        assumeTrue("TraceRA is set -> skip", !TraceRA.getValue(getInitialOptions()));
-    }
-
-    @Test
-    public void test1() {
-        testAllocation("test1snippet", 2, 0, 0);
-    }
-
-    public static long test1snippet(long x) {
-        return x + 41;
-    }
-
-    @Test
-    public void test2() {
-        testAllocation("test2snippet", 2, 0, 0);
-    }
-
-    public static long test2snippet(long x) {
-        return x * 41;
-    }
-
-    @Test
-    public void test3() {
-        testAllocation("test3snippet", 4, 0, 0);
-    }
-
-    public static long test3snippet(long x) {
-        return x / 41 + x % 41;
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java	Fri Feb 02 17:28:17 2018 -0800
@@ -29,6 +29,7 @@
 import static jdk.vm.ci.sparc.SPARCKind.XWORD;
 
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.core.match.ComplexMatchResult;
@@ -147,7 +148,7 @@
     @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
     public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
         JavaConstant constant = value.asJavaConstant();
-        assert compare.condition() == Condition.EQ;
+        assert compare.condition() == CanonicalCondition.EQ;
         if (constant != null && cas.usages().count() == 1) {
             long constantValue = constant.asLong();
             boolean successIsTrue;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest11.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest11.java	Fri Feb 02 17:28:17 2018 -0800
@@ -123,19 +123,19 @@
 
     public static int test6Snippet(int a) {
         if ((a & 8) != 0) {
-            GraalDirectives.deoptimizeAndInvalidate();
+            GraalDirectives.deoptimize();
         }
         if ((a & 15) != 15) {
-            GraalDirectives.deoptimizeAndInvalidate();
+            GraalDirectives.deoptimize();
         }
         return 0;
     }
 
     public static int reference6Snippet(int a) {
         if ((a & 8) != 0) {
-            GraalDirectives.deoptimizeAndInvalidate();
+            GraalDirectives.deoptimize();
         }
-        GraalDirectives.deoptimizeAndInvalidate();
+        GraalDirectives.deoptimize();
         return 0;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -74,7 +74,6 @@
             new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
             canonicalizer.apply(graph, context);
             canonicalizer.apply(graph, context);
-            new ConvertDeoptimizeToGuardPhase().apply(graph, context);
         } catch (Throwable t) {
             debug.handle(t);
         }
@@ -86,7 +85,6 @@
             }
             canonicalizer.apply(referenceGraph, context);
             canonicalizer.apply(referenceGraph, context);
-            new ConvertDeoptimizeToGuardPhase().apply(graph, context);
         } catch (Throwable t) {
             debug.handle(t);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,14 +25,12 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
 
-import org.graalvm.compiler.nodes.NodeView;
-import org.junit.Test;
-
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.loop.InductionVariable;
 import org.graalvm.compiler.loop.LoopsData;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
@@ -42,6 +40,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.junit.Test;
 
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -117,6 +116,21 @@
         test("incrementSnippet", 0, 256, 3);
     }
 
+    @Test
+    public void increment4() {
+        test("incrementSnippet", -10, Integer.MAX_VALUE, 1);
+    }
+
+    @Test
+    public void increment5() {
+        test("incrementSnippet", 256, 256, 1);
+    }
+
+    @Test
+    public void increment6() {
+        test("incrementSnippet", 257, 256, 1);
+    }
+
     public static Result incrementEqSnippet(int start, int limit, int step) {
         int i;
         int inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
@@ -144,6 +158,21 @@
         test("incrementEqSnippet", 0, 256, 3);
     }
 
+    @Test
+    public void incrementEq4() {
+        test("incrementEqSnippet", -10, 0, Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void incrementEq5() {
+        test("incrementEqSnippet", 256, 256, 1);
+    }
+
+    @Test
+    public void incrementEq6() {
+        test("incrementEqSnippet", 257, 256, 1);
+    }
+
     public static Result decrementSnippet(int start, int limit, int step) {
         int i;
         int dec = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
@@ -198,6 +227,11 @@
         test("decrementEqSnippet", 256, 0, 3);
     }
 
+    @Test
+    public void decrementEq4() {
+        test("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
+    }
+
     public static Result twoVariablesSnippet() {
         Result ret = new Result();
         int j = 0;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -27,10 +27,10 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Test;
 
 /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -561,7 +561,7 @@
      * @return a scheduled textual dump of {@code graph} .
      */
     protected static String getScheduledGraphString(StructuredGraph graph) {
-        SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST);
+        SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
         schedule.apply(graph);
         ScheduleResult scheduleResult = graph.getLastSchedule();
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,14 +22,14 @@
  */
 package org.graalvm.compiler.core.test;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Scope;
 import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.debug.DebugContext.Scope;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Assert;
 import org.junit.Test;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphScheduleTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphScheduleTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,20 +24,29 @@
 
 import java.util.List;
 
-import org.junit.Assert;
-
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeMap;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
 import org.graalvm.compiler.nodes.cfg.Block;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.junit.Assert;
+
+import jdk.vm.ci.meta.SpeculationLog;
 
 public class GraphScheduleTest extends GraalCompilerTest {
 
     protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
-        SchedulePhase ibp = new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST);
+        assertOrderedAfterSchedule(graph, SchedulePhase.SchedulingStrategy.LATEST, a, b);
+    }
+
+    protected void assertOrderedAfterSchedule(StructuredGraph graph, SchedulePhase.SchedulingStrategy strategy, Node a, Node b) {
+        SchedulePhase ibp = new SchedulePhase(strategy);
         ibp.apply(graph);
+        assertOrderedAfterLastSchedule(graph, a, b);
+    }
+
+    protected void assertOrderedAfterLastSchedule(StructuredGraph graph, Node a, Node b) {
         assertOrderedAfterSchedule(graph.getLastSchedule(), a, b);
     }
 
@@ -48,7 +57,7 @@
 
         if (bBlock == aBlock) {
             List<Node> instructions = ibp.nodesFor(bBlock);
-            Assert.assertTrue(instructions.indexOf(b) > instructions.indexOf(a));
+            Assert.assertTrue(a + " should be before " + b, instructions.indexOf(b) > instructions.indexOf(a));
         } else {
             Block block = bBlock;
             while (block != null) {
@@ -60,4 +69,9 @@
             Assert.fail("block of A doesn't dominate the block of B");
         }
     }
+
+    @Override
+    protected SpeculationLog getSpeculationLog() {
+        return getCodeCache().createSpeculationLog();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,131 @@
+/*
+ * 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.core.test;
+
+import static org.graalvm.compiler.graph.test.matchers.NodeIterableCount.hasCount;
+import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isNotEmpty;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Iterator;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.nodes.GuardNode;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.calc.IntegerLowerThanNode;
+import org.graalvm.compiler.nodes.calc.IsNullNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Test;
+
+public class GuardPrioritiesTest extends GraphScheduleTest {
+    private int[] array;
+    private int size;
+
+    public void growing(int e) {
+        if (size >= array.length) {
+            // grow
+            GraalDirectives.deoptimizeAndInvalidateWithSpeculation();
+        }
+        array[size++] = e;
+    }
+
+    @Test
+    public void growingTest() {
+        assumeTrue("GuardPriorities must be turned one", GraalOptions.GuardPriorities.getValue(getInitialOptions()));
+        StructuredGraph graph = prepareGraph("growing");
+
+        NodeIterable<GuardNode> guards = graph.getNodes(GuardNode.TYPE).filter(n -> n.inputs().filter(i -> i instanceof IntegerLowerThanNode).isNotEmpty());
+        assertThat(guards, isNotEmpty());
+        assumeThat(guards, hasCount(2));
+
+        Iterator<GuardNode> iterator = guards.iterator();
+        GuardNode g1 = iterator.next();
+        GuardNode g2 = iterator.next();
+        assertTrue("There should be one guard with speculation, the other one without", g1.getSpeculation().isNull() ^ g2.getSpeculation().isNull());
+        GuardNode withSpeculation = g1.getSpeculation().isNull() ? g2 : g1;
+        GuardNode withoutSpeculation = g1.getSpeculation().isNull() ? g1 : g2;
+
+        assertOrderedAfterSchedule(graph, SchedulePhase.SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER, withSpeculation, withoutSpeculation);
+    }
+
+    private StructuredGraph prepareGraph(String method) {
+        StructuredGraph graph = parseEager(method, StructuredGraph.AllowAssumptions.YES);
+        HighTierContext highTierContext = getDefaultHighTierContext();
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        new ConvertDeoptimizeToGuardPhase().apply(graph, highTierContext);
+        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
+        new FloatingReadPhase().apply(graph);
+        return graph;
+    }
+
+    public int unknownCondition(Integer c, Object o, int[] a, Integer i) {
+        if (o != null) {
+            GraalDirectives.deoptimizeAndInvalidate();
+        }
+        if (i > 5560) {
+            GraalDirectives.deoptimizeAndInvalidate();
+        }
+        if (c >= 10) {
+            GraalDirectives.deoptimizeAndInvalidateWithSpeculation();
+        }
+        return array[8] + a[i];
+    }
+
+    @Test
+    public void unknownTest() {
+        assumeTrue("GuardPriorities must be turned one", GraalOptions.GuardPriorities.getValue(getInitialOptions()));
+        StructuredGraph graph = prepareGraph("unknownCondition");
+
+        new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER).apply(graph);
+        for (GuardNode g1 : graph.getNodes(GuardNode.TYPE)) {
+            for (GuardNode g2 : graph.getNodes(GuardNode.TYPE)) {
+                if (g1.getSpeculation().isNull() ^ g2.getSpeculation().isNull()) {
+                    GuardNode withSpeculation = g1.getSpeculation().isNull() ? g2 : g1;
+                    GuardNode withoutSpeculation = g1.getSpeculation().isNull() ? g1 : g2;
+
+                    if (withoutSpeculation.isNegated() && withoutSpeculation.getCondition() instanceof IsNullNode) {
+                        IsNullNode isNullNode = (IsNullNode) withoutSpeculation.getCondition();
+                        if (isNullNode.getValue() instanceof ParameterNode && ((ParameterNode) isNullNode.getValue()).index() == 1) {
+                            // this is the null check before the speculative guard, it's the only
+                            // one that should be above
+                            assertOrderedAfterLastSchedule(graph, withoutSpeculation, withSpeculation);
+                            continue;
+                        }
+                    }
+
+                    assertOrderedAfterLastSchedule(graph, withSpeculation, withoutSpeculation);
+                }
+            }
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -44,7 +44,7 @@
 
     public static final int N = 10000;
 
-    private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST};
+    private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER};
 
     @Test
     public void testLongAddChain() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java	Fri Feb 02 17:28:17 2018 -0800
@@ -31,13 +31,13 @@
 import java.util.Map;
 import java.util.Properties;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.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.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.MapCursor;
 
 /**
  * An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java	Fri Feb 02 17:28:17 2018 -0800
@@ -70,7 +70,7 @@
         returnNode.replaceAtPredecessor(beginNode);
         beginNode.setNext(returnNode);
         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
-        SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST);
+        SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
         schedulePhase.apply(graph);
         ScheduleResult schedule = graph.getLastSchedule();
         BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,82 @@
+/*
+ * 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.core.test;
+
+import org.graalvm.compiler.core.common.CompilationIdentifier;
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.java.BytecodeParserOptions;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Tests that the defaults for {@link GraalOptions#TrivialInliningSize} and
+ * {@link BytecodeParserOptions#InlineDuringParsingMaxDepth} prevent explosive graph growth for code
+ * with small recursive methods.
+ */
+public class TrivialInliningExplosionTest extends GraalCompilerTest {
+
+    public static void trivial() {
+        trivial();
+        trivial();
+        trivial();
+    }
+
+    public static void main() {
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+        trivial();
+    }
+
+    private int afterParseSize;
+
+    @Override
+    protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId, OptionValues options) {
+        final StructuredGraph graph = super.parseForCompile(method, compilationId, options);
+        this.afterParseSize = graph.getNodeCount();
+        return graph;
+    }
+
+    @Test
+    public void test() {
+        ResolvedJavaMethod methodm0 = getResolvedJavaMethod("trivial");
+        Assert.assertTrue(methodm0.getCodeSize() <= GraalOptions.TrivialInliningSize.getValue(getInitialOptions()));
+        test("main");
+        int afterCompileSize = lastCompiledGraph.getNodeCount();
+
+        // The values of afterParseSize and afterCompileSize when this
+        // test was written were 849 and 848 respectively.
+        Assert.assertTrue(afterParseSize < 2000);
+        Assert.assertTrue(afterCompileSize < 2000);
+
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,6 +24,7 @@
 
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
 
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.TTY;
@@ -43,7 +44,6 @@
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
-import org.graalvm.util.EconomicSet;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,6 +25,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
 import org.graalvm.compiler.core.common.GraalOptions;
@@ -64,7 +65,6 @@
 import org.graalvm.compiler.phases.tiers.Suites;
 import org.graalvm.compiler.phases.tiers.TargetProvider;
 import org.graalvm.compiler.phases.util.Providers;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.TargetDescription;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,6 +26,8 @@
 import java.util.Arrays;
 import java.util.Queue;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
@@ -42,8 +44,6 @@
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.virtual.nodes.MaterializedObjectState;
 import org.graalvm.compiler.virtual.nodes.VirtualObjectState;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.code.VirtualObject;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -33,6 +33,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.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;
@@ -100,8 +102,6 @@
 import org.graalvm.compiler.nodes.spi.NodeValueMap;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.UnmodifiableMapCursor;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.StackSlot;
@@ -538,7 +538,8 @@
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
         PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
-        gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
+        gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor,
+                        trueSuccessorProbability);
     }
 
     public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
@@ -566,7 +567,7 @@
         } else if (node instanceof CompareNode) {
             CompareNode compare = (CompareNode) node;
             PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
-            return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
+            return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueValue, falseValue);
         } else if (node instanceof LogicConstantNode) {
             return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
         } else if (node instanceof IntegerTestNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,6 +28,8 @@
 import java.util.Arrays;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
 import org.graalvm.compiler.core.match.MatchPattern.Result;
 import org.graalvm.compiler.debug.DebugContext;
@@ -35,8 +37,6 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 /**
  * Container for state captured during a match.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchRuleRegistry.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchRuleRegistry.java	Fri Feb 02 17:28:17 2018 -0800
@@ -27,6 +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 org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
@@ -36,9 +39,6 @@
 import org.graalvm.compiler.graph.Position;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.GraalServices;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.MapCursor;
 
 public class MatchRuleRegistry {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.core.phases;
 
+import org.graalvm.collections.EconomicSet;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Graph.NodeEvent;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
@@ -32,8 +34,6 @@
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
 
 /**
  * A utility phase for detecting when a phase would change the graph and reporting extra information
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
@@ -44,7 +45,6 @@
 import org.graalvm.compiler.phases.tiers.SuitesProvider;
 import org.graalvm.compiler.phases.tiers.TargetProvider;
 import org.graalvm.compiler.phases.util.Providers;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.CodeCacheProvider;
@@ -204,31 +204,48 @@
         }
         try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
                         DebugContext.Activation a = debug.activate()) {
-            for (CodeInstallationTask task : tasks) {
-                task.preProcess(compilationResult);
+            preCodeInstallationTasks(tasks, compilationResult);
+
+            InstalledCode installedCode;
+            try {
+                CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
+                installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
+            } catch (Throwable t) {
+                failCodeInstallationTasks(tasks, t);
+                throw t;
             }
 
-            CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
-            InstalledCode installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
+            postCodeInstallationTasks(tasks, installedCode);
 
-            // Run post-code installation tasks.
-            try {
-                for (CodeInstallationTask task : tasks) {
-                    task.postProcess(installedCode);
-                }
-                for (CodeInstallationTask task : tasks) {
-                    task.releaseInstallation(installedCode);
-                }
-            } catch (Throwable t) {
-                installedCode.invalidate();
-                throw t;
-            }
             return installedCode;
         } catch (Throwable e) {
             throw debug.handle(e);
         }
     }
 
+    private static void failCodeInstallationTasks(CodeInstallationTask[] tasks, Throwable t) {
+        for (CodeInstallationTask task : tasks) {
+            task.installFailed(t);
+        }
+    }
+
+    private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) {
+        for (CodeInstallationTask task : tasks) {
+            task.preProcess(compilationResult);
+        }
+    }
+
+    private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) {
+        try {
+            for (CodeInstallationTask task : tasks) {
+                task.postProcess(installedCode);
+            }
+        } catch (Throwable t) {
+            installedCode.invalidate();
+            throw t;
+        }
+    }
+
     /**
      * Installs code based on a given compilation result.
      *
@@ -301,11 +318,10 @@
         }
 
         /**
-         * Task to run after all the post-code installation tasks are complete, used to release the
-         * installed code.
+         * Invoked after {@link #preProcess} when code installation fails.
          */
         @SuppressWarnings("unused")
-        public void releaseInstallation(InstalledCode installedCode) {
+        public void installFailed(Throwable t) {
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -34,6 +34,7 @@
 import java.util.Formatter;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
@@ -46,7 +47,6 @@
 import org.graalvm.compiler.debug.DebugVerifyHandler;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Test;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -30,6 +30,7 @@
 
 import java.lang.management.ThreadMXBean;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugOptions;
@@ -37,7 +38,6 @@
 import org.graalvm.compiler.debug.TimerKey;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CounterKeyImpl.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CounterKeyImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.debug;
 
-import org.graalvm.util.Pair;
+import org.graalvm.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/DebugContext.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Fri Feb 02 17:28:17 2018 -0800
@@ -56,12 +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 org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.graphio.GraphOutput;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Pair;
 
 import jdk.vm.ci.meta.JavaMethod;
 
@@ -1937,10 +1937,17 @@
         if (description != null) {
             printMetrics(description);
         }
-        if (metricsEnabled && globalMetrics != null && metricValues != null) {
+        if (metricsEnabled && metricValues != null && globalMetrics != null) {
             globalMetrics.add(this);
         }
         metricValues = null;
+        if (sharedChannel != null) {
+            try {
+                sharedChannel.realClose();
+            } catch (IOException ex) {
+                // ignore.
+            }
+        }
     }
 
     public void closeDumpHandlers(boolean ignoreErrors) {
@@ -2022,7 +2029,6 @@
                 }
             }
         }
-
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Fri Feb 02 17:28:17 2018 -0800
@@ -27,11 +27,11 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
+import org.graalvm.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.util.EconomicMap;
 
 /**
  * Options that configure a {@link DebugContext} and related functionality.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java	Fri Feb 02 17:28:17 2018 -0800
@@ -29,10 +29,10 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.MapCursor;
+import org.graalvm.collections.Pair;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.MapCursor;
-import org.graalvm.util.Pair;
 
 /**
  * Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/KeyRegistry.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/KeyRegistry.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,7 +25,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.util.EconomicMap;
+import org.graalvm.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/MemUseTrackerKeyImpl.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKeyImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,7 +24,7 @@
 
 import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
 
-import org.graalvm.util.Pair;
+import org.graalvm.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	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MetricKey.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,7 +24,7 @@
 
 import java.util.Comparator;
 
-import org.graalvm.util.Pair;
+import org.graalvm.collections.Pair;
 
 /**
  * A key for a metric.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,7 +26,7 @@
 
 import java.util.concurrent.TimeUnit;
 
-import org.graalvm.util.Pair;
+import org.graalvm.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/src/org/graalvm/compiler/graph/CachedGraph.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/CachedGraph.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,7 +24,7 @@
 
 import java.util.function.Consumer;
 
-import org.graalvm.util.UnmodifiableEconomicMap;
+import org.graalvm.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	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Fri Feb 02 17:28:17 2018 -0800
@@ -30,6 +30,9 @@
 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 org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
@@ -41,9 +44,6 @@
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.UnmodifiableEconomicMap;
 
 /**
  * This class is a graph container, it contains the set of nodes that belong to this graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeBitMap.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeBitMap.java	Fri Feb 02 17:28:17 2018 -0800
@@ -160,6 +160,12 @@
         }
     }
 
+    public void invert() {
+        for (int i = 0; i < bits.length; i++) {
+            bits[i] = ~bits[i];
+        }
+    }
+
     public void grow() {
         nodeCount = Math.max(nodeCount, graph().nodeIdCount());
         int newLength = sizeForNodeCount(nodeCount);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Fri Feb 02 17:28:17 2018 -0800
@@ -42,6 +42,8 @@
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.core.common.FieldIntrospection;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.core.common.FieldsScanner;
@@ -65,8 +67,6 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 /**
  * Metadata for every {@link Node} type. The metadata includes:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,8 +26,8 @@
 import java.util.Iterator;
 import java.util.function.BiFunction;
 
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.MapCursor;
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.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/NodeStack.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeStack.java	Fri Feb 02 17:28:17 2018 -0800
@@ -74,6 +74,10 @@
         return tos == 0;
     }
 
+    public void clear() {
+        tos = 0;
+    }
+
     @Override
     public String toString() {
         if (tos == 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,7 +22,6 @@
  */
 package org.graalvm.compiler.hotspot.aarch64;
 
-import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
 import static java.lang.reflect.Modifier.isStatic;
 import static jdk.vm.ci.aarch64.AArch64.lr;
 import static jdk.vm.ci.aarch64.AArch64.r10;
@@ -30,7 +29,9 @@
 import static jdk.vm.ci.aarch64.AArch64.zr;
 import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
+import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
 
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
@@ -42,11 +43,11 @@
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
 import org.graalvm.compiler.hotspot.stubs.Stub;
@@ -64,7 +65,6 @@
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.Register;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Fri Feb 02 17:28:17 2018 -0800
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
 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.options.OptionValues;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
@@ -136,7 +137,7 @@
                 replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
-                plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
+                plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
                 replacements.setGraphBuilderPlugins(plugins);
             }
             try (InitTimer rt = timer("create Suites provider")) {
@@ -152,9 +153,10 @@
     }
 
     protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
-                    HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements,
-                    HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
-        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
+                    HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
+                    HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
+        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
+                        replacements);
         AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
         return plugins;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/ArrayAccessInLoopToAddressTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.amd64.test;
+
+import jdk.vm.ci.hotspot.HotSpotSpeculationLog;
+import jdk.vm.ci.meta.SpeculationLog;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.junit.Test;
+
+public class ArrayAccessInLoopToAddressTest extends GraalCompilerTest {
+
+    public static int positiveInductionVariable(short[] array) {
+        int sum = 0;
+        for (int i = 0; i < array.length - 1; i++) {
+            sum += array[i + 1];
+        }
+        return sum;
+    }
+
+    @Test
+    public void testPositiveInductionVariable() {
+        test("positiveInductionVariable", new short[]{1, 3, 7, 9});
+    }
+
+    public static int negativeInductionVariable(short[] array) {
+        int sum = 0;
+        for (int i = -array.length; i < array.length - 4; i++) {
+            sum += array[i + 4];
+        }
+        return sum;
+    }
+
+    @Test
+    public void testNegativeInductionVariable() {
+        test("negativeInductionVariable", new short[]{1, 3, 7, 9});
+    }
+
+    @Override
+    protected SpeculationLog getSpeculationLog() {
+        return new HotSpotSpeculationLog();
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,64 +24,50 @@
 package org.graalvm.compiler.hotspot.amd64;
 
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
-import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
 import org.graalvm.compiler.core.amd64.AMD64AddressNode;
+import org.graalvm.compiler.core.amd64.AMD64CompressAddressLowering;
 import org.graalvm.compiler.core.common.CompressEncoding;
-import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.debug.CounterKey;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.loop.BasicInductionVariable;
+import org.graalvm.compiler.loop.CountedLoopInfo;
+import org.graalvm.compiler.loop.DerivedInductionVariable;
+import org.graalvm.compiler.loop.InductionVariable;
+import org.graalvm.compiler.loop.LoopEx;
+import org.graalvm.compiler.loop.LoopsData;
 import org.graalvm.compiler.nodes.CompressionNode;
-import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.calc.FloatingNode;
-import org.graalvm.compiler.nodes.spi.LIRLowerable;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.SignExtendNode;
+import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
 import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.JavaKind;
 
-public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
+public class AMD64HotSpotAddressLowering extends AMD64CompressAddressLowering {
 
-    private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering");
+    private static final int ADDRESS_BITS = 64;
+    private static final int INT_BITS = 32;
 
     private final long heapBase;
     private final Register heapBaseRegister;
     private final GraalHotSpotVMConfig config;
     private final boolean generatePIC;
 
-    @NodeInfo(cycles = CYCLES_0, size = SIZE_0)
-    public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
-
-        public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
-
-        private final Register heapBaseRegister;
-
-        public HeapBaseNode(Register heapBaseRegister) {
-            super(TYPE, StampFactory.pointer());
-            this.heapBaseRegister = heapBaseRegister;
-        }
-
-        @Override
-        public void generate(NodeLIRBuilderTool generator) {
-            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
-            generator.setResult(this, heapBaseRegister.asValue(kind));
-        }
-    }
-
     public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister, OptionValues options) {
         this.heapBase = config.getOopEncoding().getBase();
         this.config = config;
@@ -94,35 +80,7 @@
     }
 
     @Override
-    protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
-        if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
-            return true;
-        }
-
-        if (addr.getScale() == Scale.Times1) {
-            if (addr.getIndex() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
-                    counterFoldedUncompressDuringAddressLowering.increment(debug);
-                    return true;
-                }
-            }
-
-            if (addr.getBase() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
-                    counterFoldedUncompressDuringAddressLowering.increment(debug);
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
-        if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
-            return false;
-        }
-
+    protected final boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
         CompressEncoding encoding = compression.getEncoding();
         Scale scale = Scale.fromShift(encoding.getShift());
         if (scale == null) {
@@ -147,7 +105,7 @@
                     return false;
                 }
             } else {
-                if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
+                if (updateDisplacement(addr, encoding.getBase(), false)) {
                     addr.setBase(other);
                 } else {
                     return false;
@@ -161,4 +119,117 @@
         addr.setIndex(compression.getValue());
         return true;
     }
+
+    @Override
+    public void preProcess(StructuredGraph graph) {
+        if (graph.hasLoops()) {
+            LoopsData loopsData = new LoopsData(graph);
+            loopsData.detectedCountedLoops();
+            for (LoopEx loop : loopsData.countedLoops()) {
+                for (OffsetAddressNode offsetAdressNode : loop.whole().nodes().filter(OffsetAddressNode.class)) {
+                    tryOptimize(offsetAdressNode, loop);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void postProcess(AddressNode lowered) {
+        // Allow implicit zero extend for always positive input. This
+        // assumes that the upper bits of the operand is zero out by
+        // the backend.
+        AMD64AddressNode address = (AMD64AddressNode) lowered;
+        address.setBase(tryImplicitZeroExtend(address.getBase()));
+        address.setIndex(tryImplicitZeroExtend(address.getIndex()));
+    }
+
+    private static void tryOptimize(OffsetAddressNode offsetAddress, LoopEx loop) {
+        EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
+        InductionVariable currentIV = ivs.get(offsetAddress.getOffset());
+        while (currentIV != null) {
+            if (!(currentIV instanceof DerivedInductionVariable)) {
+                break;
+            }
+            ValueNode currentValue = currentIV.valueNode();
+            if (currentValue.isDeleted()) {
+                break;
+            }
+
+            if (currentValue instanceof ZeroExtendNode) {
+                ZeroExtendNode zeroExtendNode = (ZeroExtendNode) currentValue;
+                if (applicableToImplicitZeroExtend(zeroExtendNode)) {
+                    ValueNode input = zeroExtendNode.getValue();
+                    if (input instanceof AddNode) {
+                        AddNode add = (AddNode) input;
+                        if (add.getX().isConstant()) {
+                            optimizeAdd(zeroExtendNode, (ConstantNode) add.getX(), add.getY(), loop);
+                        } else if (add.getY().isConstant()) {
+                            optimizeAdd(zeroExtendNode, (ConstantNode) add.getY(), add.getX(), loop);
+                        }
+                    }
+                }
+            }
+
+            currentIV = ((DerivedInductionVariable) currentIV).getBase();
+        }
+    }
+
+    /**
+     * Given that Add(a, cst) is always positive, performs the following: ZeroExtend(Add(a, cst)) ->
+     * Add(SignExtend(a), SignExtend(cst)).
+     */
+    private static void optimizeAdd(ZeroExtendNode zeroExtendNode, ConstantNode constant, ValueNode other, LoopEx loop) {
+        StructuredGraph graph = zeroExtendNode.graph();
+        AddNode addNode = graph.unique(new AddNode(signExtend(other, loop), ConstantNode.forLong(constant.asJavaConstant().asInt(), graph)));
+        zeroExtendNode.replaceAtUsages(addNode);
+    }
+
+    /**
+     * Create a sign extend for {@code input}, or zero extend if {@code input} can be proven
+     * positive.
+     */
+    private static ValueNode signExtend(ValueNode input, LoopEx loop) {
+        StructuredGraph graph = input.graph();
+        if (input instanceof PhiNode) {
+            EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
+            InductionVariable inductionVariable = ivs.get(input);
+            if (inductionVariable != null && inductionVariable instanceof BasicInductionVariable) {
+                CountedLoopInfo countedLoopInfo = loop.counted();
+                IntegerStamp initStamp = (IntegerStamp) inductionVariable.initNode().stamp(NodeView.DEFAULT);
+                if (initStamp.isPositive()) {
+                    if (inductionVariable.isConstantExtremum()) {
+                        long init = inductionVariable.constantInit();
+                        long stride = inductionVariable.constantStride();
+                        long extremum = inductionVariable.constantExtremum();
+
+                        if (init >= 0 && extremum >= 0) {
+                            long shortestTrip = (extremum - init) / stride + 1;
+                            if (shortestTrip == countedLoopInfo.constantMaxTripCount()) {
+                                return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
+                            }
+                        }
+                    }
+                    if (countedLoopInfo.getCounter() == inductionVariable && inductionVariable.direction() == InductionVariable.Direction.Up && countedLoopInfo.getOverFlowGuard() != null) {
+                        return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
+                    }
+                }
+            }
+        }
+        return input.graph().maybeAddOrUnique(SignExtendNode.create(input, ADDRESS_BITS, NodeView.DEFAULT));
+    }
+
+    private static boolean applicableToImplicitZeroExtend(ZeroExtendNode zeroExtendNode) {
+        return zeroExtendNode.isInputAlwaysPositive() && zeroExtendNode.getInputBits() == INT_BITS && zeroExtendNode.getResultBits() == ADDRESS_BITS;
+    }
+
+    private static ValueNode tryImplicitZeroExtend(ValueNode input) {
+        if (input instanceof ZeroExtendNode) {
+            ZeroExtendNode zeroExtendNode = (ZeroExtendNode) input;
+            if (applicableToImplicitZeroExtend(zeroExtendNode)) {
+                return zeroExtendNode.getValue();
+            }
+        }
+        return input;
+    }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Fri Feb 02 17:28:17 2018 -0800
@@ -30,6 +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 org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
@@ -66,7 +67,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64Kind;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Fri Feb 02 17:28:17 2018 -0800
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
 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.tiers.CompilerConfiguration;
@@ -137,7 +138,7 @@
                 replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
-                plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes,
+                plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes,
                                 stampProvider);
                 replacements.setGraphBuilderPlugins(plugins);
             }
@@ -154,9 +155,10 @@
     }
 
     protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
-                    HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess,
+                    HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess,
                     HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
-        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
+        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
+                        replacements);
         AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options));
         return plugins;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Feb 02 17:28:17 2018 -0800
@@ -572,7 +572,7 @@
         if (inputKind.isReference(0)) {
             // oop
             Variable result = newVariable(lirKindTool.getNarrowOopKind());
-            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
+            append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
             return result;
         } else {
             // metaspace pointer
@@ -589,7 +589,7 @@
                     base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
+            append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
             return result;
         }
     }
@@ -602,7 +602,7 @@
         if (inputKind.isReference(0)) {
             // oop
             Variable result = newVariable(lirKindTool.getObjectKind());
-            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
+            append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
             return result;
         } else {
             // metaspace pointer
@@ -620,7 +620,7 @@
                     base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
+            append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
             return result;
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Fri Feb 02 17:28:17 2018 -0800
@@ -67,7 +67,8 @@
     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
         convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
         profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options)
-                        ? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget()) : null;
+                        ? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget())
+                        : null;
         super.initialize(options, factories, providers, config);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Fri Feb 02 17:28:17 2018 -0800
@@ -60,6 +60,7 @@
         crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
         // This must be emitted exactly like this to ensure it's patchable
         masm.movq(AMD64.rax, config.nonOopBits);
-        super.emitCode(crb, masm);
+        int offset = super.emitCall(crb, masm);
+        crb.recordInvokeVirtualOrInterfaceCallOp(offset, getPosition());
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java	Fri Feb 02 17:28:17 2018 -0800
@@ -70,7 +70,8 @@
         crb.recordMark(config.MARKID_INLINE_INVOKE);
         Register callReg = asRegister(targetAddress);
         assert !callReg.equals(METHOD);
-        AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
+        int pcOffset = AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
+        crb.recordInlineInvokeCallOp(pcOffset, getPosition());
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc.test/src/org/graalvm/compiler/core/sparc/test/SPARCAllocatorTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, 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.core.sparc.test;
+
+import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure;
+import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
+import static org.junit.Assume.assumeTrue;
+
+import org.graalvm.compiler.core.test.backend.AllocatorTest;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.junit.Before;
+import org.junit.Test;
+
+import jdk.vm.ci.sparc.SPARC;
+
+public class SPARCAllocatorTest extends AllocatorTest {
+
+    private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig();
+
+    @Before
+    public void checkSPARC() {
+        assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
+        assumeTrue("RegisterPressure is set -> skip", RegisterPressure.getValue(getInitialOptions()) == null);
+        assumeTrue("TraceRA is set -> skip", !TraceRA.getValue(getInitialOptions()));
+    }
+
+    @Test
+    public void test1() {
+        testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
+    }
+
+    public static long test1snippet(long x) {
+        return x + 41;
+    }
+
+    @Test
+    public void test2() {
+        testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
+    }
+
+    public static long test2snippet(long x) {
+        return x * 41;
+    }
+
+    @Test
+    public void test3() {
+        testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0);
+    }
+
+    public static long test3snippet(long x) {
+        return x / 41 + x % 41;
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java	Fri Feb 02 17:28:17 2018 -0800
@@ -46,6 +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 org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.sparc.SPARCAddress;
@@ -92,9 +95,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.Register;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Fri Feb 02 17:28:17 2018 -0800
@@ -101,7 +101,7 @@
         HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
         BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
         HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target);
-        Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes);
+        Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, lowerer, stampProvider, snippetReflection, replacements, wordTypes);
         replacements.setGraphBuilderPlugins(plugins);
         HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
@@ -112,9 +112,10 @@
     }
 
     protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess,
-                    HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider,
+                    HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotStampProvider stampProvider,
                     HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
-        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
+        Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
+                        replacements);
         SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
         return plugins;
     }
--- /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/ArrayNewInstanceTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,107 @@
+/*
+ * 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.test;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ArrayNewInstanceTest extends GraalCompilerTest {
+
+    @Parameters(name = "{index}: class {0} length {1}")
+    public static Iterable<Object[]> data() {
+        ArrayList<Object[]> parameters = new ArrayList<>();
+        Class<?>[] classesToTest = new Class<?>[]{
+                        byte.class,
+                        boolean.class,
+                        short.class,
+                        char.class,
+                        int.class,
+                        long.class,
+                        Void.class,
+                        ArrayNewInstanceTest.class
+        };
+        for (Class<?> clazz : classesToTest) {
+            // Negative sizes always deopt
+            parameters.add(new Object[]{clazz, -1, true});
+            parameters.add(new Object[]{clazz, 0, false});
+            parameters.add(new Object[]{clazz, 42, false});
+        }
+        // The void type always throws an exception where graal deopts
+        parameters.add(new Object[]{void.class, -1, true});
+        parameters.add(new Object[]{void.class, 0, true});
+        parameters.add(new Object[]{void.class, 42, true});
+        return parameters;
+    }
+
+    private final Class<?> type;
+    private final int length;
+    private final boolean shouldDeopt;
+    private final DeoptimizationBox box = new DeoptimizationBox();
+
+    public ArrayNewInstanceTest(Class<?> type, int length, boolean shouldDeopt) {
+        super();
+        this.type = type;
+        this.length = length;
+        this.shouldDeopt = shouldDeopt;
+    }
+
+    public static Object newArray(Class<?> klass, int length, DeoptimizationBox box) {
+        Object result = Array.newInstance(klass, length);
+        box.inCompiledCode = GraalDirectives.inCompiledCode();
+        return result;
+    }
+
+    @Test
+    public void testNewArray() {
+        test("newArray", type, length, box);
+        assertTrue(box.inCompiledCode != shouldDeopt);
+    }
+
+    public static Object newArrayInLoop(Class<?> klass, int length, int iterations, DeoptimizationBox box) {
+        Object o = null;
+        for (int i = 0; i < iterations; i++) {
+            o = Array.newInstance(klass, length);
+        }
+        box.inCompiledCode = GraalDirectives.inCompiledCode();
+        return o;
+    }
+
+    @Test
+    public void testNewArrayInLoop() {
+        test("newArrayInLoop", type, length, 2, box);
+        assertTrue(box.inCompiledCode != shouldDeopt);
+    }
+
+    private static class DeoptimizationBox {
+        volatile boolean inCompiledCode = false;
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Fri Feb 02 17:28:17 2018 -0800
@@ -32,6 +32,8 @@
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.MapCursor;
 import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@@ -43,8 +45,6 @@
 import org.graalvm.compiler.runtime.RuntimeProvider;
 import org.graalvm.compiler.serviceprovider.JDK9Method;
 import org.graalvm.compiler.test.GraalTest;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.MapCursor;
 import org.junit.Test;
 
 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
@@ -416,6 +416,12 @@
                             "java/lang/StringUTF16.toBytes([CII)[B");
         }
 
+        if (isJDK10OrHigher()) {
+            add(TO_BE_INVESTIGATED,
+                            "java/lang/Math.multiplyHigh(JJ)J",
+                            "jdk/internal/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I");
+        }
+
         if (!getHostArchitectureName().equals("amd64")) {
             // Can we implement these on non-AMD64 platforms? C2 seems to.
             add(TO_BE_INVESTIGATED,
@@ -539,6 +545,10 @@
         return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
     }
 
+    private static boolean isJDK10OrHigher() {
+        return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10;
+    }
+
     private static String getHostArchitectureName() {
         String arch = System.getProperty("os.arch");
         if (arch.equals("x86_64")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Fri Feb 02 17:28:17 2018 -0800
@@ -68,6 +68,8 @@
 import java.util.jar.JarFile;
 import java.util.stream.Collectors;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.bytecode.Bytecodes;
 import org.graalvm.compiler.core.CompilerThreadFactory;
@@ -85,8 +87,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.options.OptionsParser;
 import org.graalvm.compiler.serviceprovider.JDK9Method;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.UnmodifiableEconomicMap;
 
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,12 +25,12 @@
 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Test;
 
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -32,6 +32,7 @@
 import java.util.HashSet;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.debug.DebugContext;
@@ -40,13 +41,12 @@
 import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
 import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
-import org.junit.Assume;
-import org.junit.BeforeClass;
 
 /**
  * Test on-stack-replacement with locks.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -31,8 +31,8 @@
 
 import java.lang.management.ManagementFactory;
 import java.lang.reflect.Field;
+import java.util.Arrays;
 
-import java.util.Arrays;
 import javax.management.Attribute;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanInfo;
@@ -41,11 +41,11 @@
 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.graalvm.util.EconomicMap;
 import org.junit.Assume;
 import org.junit.Test;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Fri Feb 02 17:28:17 2018 -0800
@@ -23,8 +23,10 @@
 package org.graalvm.compiler.hotspot.test;
 
 import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
+
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
@@ -36,10 +38,9 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
+import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
 import org.graalvm.compiler.runtime.RuntimeProvider;
-import org.graalvm.util.EconomicMap;
 import org.junit.Test;
 
 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,6 +24,7 @@
 
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugContext.Scope;
@@ -58,7 +59,6 @@
 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.util.EconomicMap;
 import org.graalvm.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.Test;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Fri Feb 02 17:28:17 2018 -0800
@@ -29,6 +29,7 @@
 
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.CompilationPrinter;
@@ -45,7 +46,6 @@
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.CodeCacheProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Fri Feb 02 17:28:17 2018 -0800
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
@@ -36,7 +37,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.serviceprovider.GraalServices;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.common.InitTimer;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Fri Feb 02 17:28:17 2018 -0800
@@ -64,10 +64,10 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.tiers.SuitesProvider;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.MapCursor;
+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.vm.ci.code.CompilationRequest;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -98,8 +98,8 @@
 
         ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
         Builder<DataPatch> patchBuilder = Stream.builder();
-        data.buildDataSection(buffer, vmConstant -> {
-            patchBuilder.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
+        data.buildDataSection(buffer, (position, vmConstant) -> {
+            patchBuilder.accept(new DataPatch(position, new ConstantReference(vmConstant)));
         });
 
         int dataSectionAlignment = data.getSectionAlignment();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,11 +22,13 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
 
 import java.util.Arrays;
+
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.debug.GraalError;
@@ -34,7 +36,6 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
 import org.graalvm.compiler.lir.LIRInstruction;
 import org.graalvm.compiler.lir.LIRInstructionClass;
-import org.graalvm.util.EconomicMap;
 
 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/HotSpotDataBuilder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotDataBuilder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -56,41 +56,30 @@
 
     @Override
     public Data createDataItem(Constant constant) {
-        int size;
-        if (constant instanceof VMConstant) {
+        if (JavaConstant.isNull(constant)) {
+            boolean compressed = COMPRESSED_NULL.equals(constant);
+            int size = compressed ? 4 : target.wordSize;
+            return ZeroData.create(size, size);
+        } else if (constant instanceof VMConstant) {
             VMConstant vmConstant = (VMConstant) constant;
-            boolean compressed;
-            if (constant instanceof HotSpotConstant) {
-                HotSpotConstant c = (HotSpotConstant) vmConstant;
-                compressed = c.isCompressed();
-            } else {
+            if (!(constant instanceof HotSpotConstant)) {
                 throw new GraalError(String.valueOf(constant));
             }
 
-            size = compressed ? 4 : target.wordSize;
-            if (size == 4) {
-                return new Data(size, size) {
-
-                    @Override
-                    protected void emit(ByteBuffer buffer, Patches patches) {
-                        patches.registerPatch(vmConstant);
+            HotSpotConstant c = (HotSpotConstant) vmConstant;
+            int size = c.isCompressed() ? 4 : target.wordSize;
+            return new Data(size, size) {
+                @Override
+                protected void emit(ByteBuffer buffer, Patches patches) {
+                    int position = buffer.position();
+                    if (getSize() == Integer.BYTES) {
                         buffer.putInt(0xDEADDEAD);
-                    }
-                };
-            } else {
-                return new Data(size, size) {
-
-                    @Override
-                    protected void emit(ByteBuffer buffer, Patches patches) {
-                        patches.registerPatch(vmConstant);
+                    } else {
                         buffer.putLong(0xDEADDEADDEADDEADL);
                     }
-                };
-            }
-        } else if (JavaConstant.isNull(constant)) {
-            boolean compressed = COMPRESSED_NULL.equals(constant);
-            size = compressed ? 4 : target.wordSize;
-            return ZeroData.create(size, size);
+                    patches.registerPatch(position, vmConstant);
+                }
+            };
         } else if (constant instanceof SerializableConstant) {
             SerializableConstant s = (SerializableConstant) constant;
             return new SerializableData(s);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,15 +22,15 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 
+import org.graalvm.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.util.EconomicSet;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.code.CallingConvention;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Fri Feb 02 17:28:17 2018 -0800
@@ -44,10 +44,10 @@
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.options.OptionsParser;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.UnmodifiableEconomicMap;
+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;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java	Fri Feb 02 17:28:17 2018 -0800
@@ -30,6 +30,7 @@
 import java.util.Map;
 import java.util.Properties;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionDescriptors;
 import org.graalvm.compiler.options.OptionKey;
@@ -37,7 +38,6 @@
 import org.graalvm.compiler.options.OptionValuesAccess;
 import org.graalvm.compiler.options.OptionsParser;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.common.InitTimer;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Fri Feb 02 17:28:17 2018 -0800
@@ -34,6 +34,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.api.runtime.GraalRuntime;
 import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
@@ -57,8 +59,6 @@
 import org.graalvm.compiler.replacements.SnippetCounter;
 import org.graalvm.compiler.replacements.SnippetCounter.Group;
 import org.graalvm.compiler.runtime.RuntimeProvider;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.stack.StackIntrospection;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.hotspot.stubs.Stub;
 import org.graalvm.compiler.lir.LIR;
@@ -29,8 +31,6 @@
 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
-import org.graalvm.util.Equivalence;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.StackSlot;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Fri Feb 02 17:28:17 2018 -0800
@@ -30,6 +30,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
@@ -42,7 +43,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.util.EconomicMap;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.code.CallingConvention;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri Feb 02 17:28:17 2018 -0800
@@ -31,6 +31,7 @@
 import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MutableCallSite;
 import java.lang.invoke.VolatileCallSite;
+import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.math.BigInteger;
@@ -39,17 +40,20 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.core.common.type.TypeReference;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
 import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
 import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
+import org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions;
 import org.graalvm.compiler.hotspot.replacements.CRC32Substitutions;
-import org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions;
 import org.graalvm.compiler.hotspot.replacements.CallSiteTargetNode;
 import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
 import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
+import org.graalvm.compiler.hotspot.replacements.HotSpotArraySubstitutions;
 import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
 import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
 import org.graalvm.compiler.hotspot.replacements.ObjectCloneNode;
@@ -68,7 +72,6 @@
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
 import org.graalvm.compiler.nodes.NodeView;
-import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
@@ -83,8 +86,10 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
 import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+import org.graalvm.compiler.nodes.memory.ReadNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.StampProvider;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
@@ -123,12 +128,12 @@
      * @param stampProvider
      */
     public static Plugins create(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess,
-                    ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider,
-                    ReplacementsImpl replacements) {
+                    ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, LoweringProvider lowerer,
+                    StampProvider stampProvider, ReplacementsImpl replacements) {
         InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, compilerConfiguration);
 
         Plugins plugins = new Plugins(invocationPlugins);
-        NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes);
+        NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, lowerer, wordTypes);
         HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
         HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin);
 
@@ -171,6 +176,7 @@
                 registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
                 registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
                 StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true);
+                registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
 
                 for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
                     factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
@@ -401,19 +407,23 @@
         });
     }
 
+    private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
+        Registration r = new Registration(plugins, Array.class, bytecodeProvider);
+        r.setAllowOverwrite(true);
+        r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
+    }
+
     private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
         Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
         r.register0("currentThread", new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
-                boolean compressible = false;
                 ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
                 AddressNode address = b.add(new OffsetAddressNode(thread, offset));
-                ValueNode javaThread = WordOperationPlugin.readOp(b, JavaKind.Object, address, JAVA_THREAD_THREAD_OBJECT_LOCATION, BarrierType.NONE, compressible);
-                boolean exactType = false;
-                boolean nonNull = true;
-                b.addPush(JavaKind.Object, new PiNode(javaThread, metaAccess.lookupJavaType(Thread.class), exactType, nonNull));
+                // JavaThread::_threadObj is never compressed
+                ObjectStamp stamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), metaAccess.lookupJavaType(Thread.class)));
+                b.addPush(JavaKind.Object, new ReadNode(address, JAVA_THREAD_THREAD_OBJECT_LOCATION, stamp, BarrierType.NONE));
                 return true;
             }
         });
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Feb 02 17:28:17 2018 -0800
@@ -101,6 +101,7 @@
 
 import java.util.EnumMap;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.debug.GraalError;
@@ -123,7 +124,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
-import org.graalvm.util.EconomicMap;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeCacheProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java	Fri Feb 02 17:28:17 2018 -0800
@@ -27,6 +27,7 @@
 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;
@@ -42,7 +43,6 @@
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.replacements.nodes.MacroNode;
 import org.graalvm.compiler.serviceprovider.JDK9Method;
-import org.graalvm.util.EconomicSet;
 
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
 import jdk.vm.ci.meta.JavaKind;
@@ -122,7 +122,7 @@
      * of its module dependencies are trusted.
      */
     @Override
-    protected boolean canBeIntrinsified(ResolvedJavaType declaringClass) {
+    public boolean canBeIntrinsified(ResolvedJavaType declaringClass) {
         if (declaringClass instanceof HotSpotResolvedJavaType) {
             Class<?> javaClass = ((HotSpotResolvedJavaType) declaringClass).mirror();
             if (Java8OrEarlier) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot.meta;
 
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -104,4 +105,9 @@
         }
         return null;
     }
+
+    @Override
+    public Class<?> originalClass(ResolvedJavaType type) {
+        return ((HotSpotResolvedJavaType) type).mirror();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ArrayRangeWriteBarrier.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ArrayRangeWriteBarrier.java	Fri Feb 02 17:28:17 2018 -0800
@@ -23,34 +23,37 @@
 package org.graalvm.compiler.hotspot.nodes;
 
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 
 @NodeInfo
 public abstract class ArrayRangeWriteBarrier extends WriteBarrier implements Lowerable {
 
     public static final NodeClass<ArrayRangeWriteBarrier> TYPE = NodeClass.create(ArrayRangeWriteBarrier.class);
-    @Input ValueNode object;
-    @Input ValueNode startIndex;
+    @Input(InputType.Association) AddressNode address;
     @Input ValueNode length;
 
-    protected ArrayRangeWriteBarrier(NodeClass<? extends ArrayRangeWriteBarrier> c, ValueNode object, ValueNode startIndex, ValueNode length) {
+    private final int elementStride;
+
+    protected ArrayRangeWriteBarrier(NodeClass<? extends ArrayRangeWriteBarrier> c, AddressNode address, ValueNode length, int elementStride) {
         super(c);
-        this.object = object;
-        this.startIndex = startIndex;
+        this.address = address;
         this.length = length;
+        this.elementStride = elementStride;
     }
 
-    public ValueNode getObject() {
-        return object;
-    }
-
-    public ValueNode getStartIndex() {
-        return startIndex;
+    public AddressNode getAddress() {
+        return address;
     }
 
     public ValueNode getLength() {
         return length;
     }
+
+    public int getElementStride() {
+        return elementStride;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,13 +28,14 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
 
 @NodeInfo(cycles = CYCLES_64, size = SIZE_64)
 public class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier {
     public static final NodeClass<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class);
 
-    public G1ArrayRangePostWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) {
-        super(TYPE, object, startIndex, length);
+    public G1ArrayRangePostWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
     }
 
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,13 +28,14 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
 
 @NodeInfo(cycles = CYCLES_64, size = SIZE_64)
 public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier {
     public static final NodeClass<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class);
 
-    public G1ArrayRangePreWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) {
-        super(TYPE, object, startIndex, length);
+    public G1ArrayRangePreWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
     }
 
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,14 +28,14 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
 
 @NodeInfo(cycles = CYCLES_8, size = SIZE_8)
 public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier {
-
     public static final NodeClass<SerialArrayRangeWriteBarrier> TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class);
 
-    public SerialArrayRangeWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) {
-        super(TYPE, object, startIndex, length);
+    public SerialArrayRangeWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
     }
 
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -34,7 +34,7 @@
 import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
+import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
 import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
 import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -65,9 +65,9 @@
                 addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph);
             } else if (n instanceof AbstractCompareAndSwapNode) {
                 addCASBarriers((AbstractCompareAndSwapNode) n, graph);
-            } else if (n instanceof ArrayRangeWriteNode) {
-                ArrayRangeWriteNode node = (ArrayRangeWriteNode) n;
-                if (node.isObjectArray()) {
+            } else if (n instanceof ArrayRangeWrite) {
+                ArrayRangeWrite node = (ArrayRangeWrite) n;
+                if (node.writesObjectArray()) {
                     addArrayRangeBarriers(node, graph);
                 }
             }
@@ -171,17 +171,17 @@
         }
     }
 
-    private void addArrayRangeBarriers(ArrayRangeWriteNode node, StructuredGraph graph) {
+    private void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) {
         if (config.useG1GC) {
-            if (!node.isInitialization()) {
-                G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(node.getArray(), node.getIndex(), node.getLength()));
-                graph.addBeforeFixed(node, g1ArrayRangePreWriteBarrier);
+            if (!write.isInitialization()) {
+                G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+                graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier);
             }
-            G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(node.getArray(), node.getIndex(), node.getLength()));
-            graph.addAfterFixed(node, g1ArrayRangePostWriteBarrier);
+            G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+            graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier);
         } else {
-            SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(node.getArray(), node.getIndex(), node.getLength()));
-            graph.addAfterFixed(node, serialArrayRangeWriteBarrier);
+            SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+            graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
+import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
 import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -122,7 +122,7 @@
     private boolean hasAttachedBarrier(FixedWithNextNode node) {
         final Node next = node.next();
         final Node previous = node.predecessor();
-        boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWriteNode) node).isInitialization());
+        boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWrite) node).isInitialization());
         if (node instanceof WriteNode) {
             WriteNode writeNode = (WriteNode) node;
             if (writeNode.getLocationIdentity().isInit()) {
@@ -143,7 +143,7 @@
     }
 
     private static boolean isArrayBarrier(FixedWithNextNode node, final Node next) {
-        return (next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWriteNode) node).getArray() == ((ArrayRangeWriteBarrier) next).getObject();
+        return (next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWrite) node).getAddress() == ((ArrayRangeWriteBarrier) next).getAddress();
     }
 
     private static boolean isObjectWrite(Node node) {
@@ -152,7 +152,7 @@
     }
 
     private static boolean isObjectArrayRangeWrite(Node node) {
-        return node instanceof ArrayRangeWriteNode && ((ArrayRangeWriteNode) node).isObjectArray();
+        return node instanceof ArrayRangeWrite && ((ArrayRangeWrite) node).writesObjectArray();
     }
 
     private static void expandFrontier(NodeFlood frontier, Node node) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -28,6 +28,11 @@
 import java.util.Iterator;
 import java.util.List;
 
+import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
@@ -40,11 +45,6 @@
 import org.graalvm.compiler.phases.graph.MergeableState;
 import org.graalvm.compiler.phases.graph.PostOrderNodeIterator;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
-import org.graalvm.util.EconomicSet;
-
-import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.ResolvedJavaType;
 
 public class EliminateRedundantInitializationPhase extends BasePhase<PhaseContext> {
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Fri Feb 02 17:28:17 2018 -0800
@@ -29,6 +29,7 @@
 import java.util.HashSet;
 import java.util.List;
 
+import org.graalvm.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;
@@ -64,7 +65,6 @@
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
-import org.graalvm.util.EconomicMap;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,10 +25,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-import org.graalvm.compiler.core.common.calc.Condition;
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -56,7 +53,9 @@
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
 /**
@@ -169,8 +168,8 @@
     }
 
     @Override
-    public boolean preservesOrder(Condition op, Constant value, ConstantReflectionProvider constantReflection) {
-        assert op == Condition.EQ || op == Condition.NE;
+    public boolean preservesOrder(CanonicalCondition op, Constant value, ConstantReflectionProvider constantReflection) {
+        assert op == CanonicalCondition.EQ;
         ResolvedJavaType exactType = constantReflection.asJavaType(value);
         return !exactType.isPrimitive();
     }
--- /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/replacements/HotSpotArraySubstitutions.java	Fri Feb 02 17:28:17 2018 -0800
@@ -0,0 +1,54 @@
+/*
+ * 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.replacements;
+
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_ARRAY_KLASS_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassOffset;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadKlassFromObject;
+
+import java.lang.reflect.Array;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.nodes.java.DynamicNewArrayNode;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for {@link Array} methods.
+ */
+@ClassSubstitution(Array.class)
+public class HotSpotArraySubstitutions {
+
+    @MethodSubstitution
+    public static Object newInstance(Class<?> componentType, int length) {
+        if (componentType == null || loadKlassFromObject(componentType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION).isNull()) {
+            // Exit the intrinsic here for the case where the array class does not exist
+            return newInstance(componentType, length);
+        }
+        return DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(componentType), length);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Feb 02 17:28:17 2018 -0800
@@ -303,7 +303,11 @@
         return result;
     }
 
-    public static final LocationIdentity JAVA_THREAD_THREAD_OBJECT_LOCATION = NamedLocationIdentity.mutable("JavaThread::_threadObj");
+    /*
+     * As far as Java code is concerned this can be considered immutable: it is set just after the
+     * JavaThread is created, before it is published. After that, it is never changed.
+     */
+    public static final LocationIdentity JAVA_THREAD_THREAD_OBJECT_LOCATION = NamedLocationIdentity.immutable("JavaThread::_threadObj");
 
     @Fold
     public static int threadObjectOffset(@InjectedParameter GraalHotSpotVMConfig config) {
@@ -565,9 +569,20 @@
         return WordFactory.unsigned(ComputeObjectAddressNode.get(a, getArrayBaseOffset(JavaKind.Int)));
     }
 
+    /**
+     * Idiom for making {@link GraalHotSpotVMConfig} a constant.
+     */
     @Fold
-    public static int objectAlignment(@InjectedParameter GraalHotSpotVMConfig config) {
-        return config.objectAlignment;
+    public static GraalHotSpotVMConfig getConfig(@InjectedParameter GraalHotSpotVMConfig config) {
+        return config;
+    }
+
+    /**
+     * Calls {@link #arrayAllocationSize(int, int, int, GraalHotSpotVMConfig)} using an injected VM
+     * configuration object.
+     */
+    public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize) {
+        return arrayAllocationSize(length, headerSize, log2ElementSize, getConfig(INJECTED_VMCONFIG));
     }
 
     /**
@@ -578,10 +593,12 @@
      * @param length the number of elements in the array
      * @param headerSize the size of the array header
      * @param log2ElementSize log2 of the size of an element in the array
+     * @param config the VM configuration providing the
+     *            {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment requirement}
      * @return the size of the memory chunk
      */
-    public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize) {
-        int alignment = objectAlignment(INJECTED_VMCONFIG);
+    public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize, GraalHotSpotVMConfig config) {
+        int alignment = config.objectAlignment;
         int size = (length << log2ElementSize) + headerSize + (alignment - 1);
         int mask = ~(alignment - 1);
         return size & mask;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Fri Feb 02 17:28:17 2018 -0800
@@ -62,6 +62,7 @@
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
 import static org.graalvm.compiler.replacements.ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED;
+import static org.graalvm.compiler.replacements.ReplacementsUtil.runtimeAssert;
 import static org.graalvm.compiler.replacements.ReplacementsUtil.staticAssert;
 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
 import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring;
@@ -378,7 +379,13 @@
         if (length < 0) {
             DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
         }
-        int layoutHelper = knownElementKind != JavaKind.Illegal ? knownLayoutHelper : readLayoutHelper(nonNullKlass);
+        int layoutHelper;
+        if (knownElementKind == JavaKind.Illegal) {
+            layoutHelper = readLayoutHelper(nonNullKlass);
+        } else {
+            runtimeAssert(knownLayoutHelper == readLayoutHelper(nonNullKlass), "layout mismatch");
+            layoutHelper = knownLayoutHelper;
+        }
         //@formatter:off
         // from src/share/vm/oops/klass.hpp:
         //
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Fri Feb 02 17:28:17 2018 -0800
@@ -24,7 +24,6 @@
 
 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.cardTableShift;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.dirtyCardValue;
@@ -59,7 +58,6 @@
 import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier;
 import org.graalvm.compiler.hotspot.nodes.G1PreWriteBarrier;
 import org.graalvm.compiler.hotspot.nodes.G1ReferentFieldReadBarrier;
-import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
 import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
 import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
 import org.graalvm.compiler.hotspot.nodes.SerialArrayRangeWriteBarrier;
@@ -152,18 +150,14 @@
     }
 
     @Snippet
-    public static void serialArrayRangeWriteBarrier(Object object, int startIndex, int length) {
+    public static void serialArrayRangeWriteBarrier(Address address, int length, @ConstantParameter int elementStride) {
         if (length == 0) {
             return;
         }
-        Object dest = FixedValueAnchorNode.getObject(object);
         int cardShift = cardTableShift(INJECTED_VMCONFIG);
         final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress();
-        final int scale = arrayIndexScale(JavaKind.Object);
-        int header = arrayBaseOffset(JavaKind.Object);
-        long dstAddr = GetObjectAddressNode.get(dest);
-        long start = (dstAddr + header + (long) startIndex * scale) >>> cardShift;
-        long end = (dstAddr + header + ((long) startIndex + length - 1) * scale) >>> cardShift;
+        long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift;
+        long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift;
         long count = end - start + 1;
         while (count-- > 0) {
             DirectStoreNode.storeBoolean((start + cardStart) + count, false, JavaKind.Boolean);
@@ -305,24 +299,22 @@
     }
 
     @Snippet
-    public static void g1ArrayRangePreWriteBarrier(Object object, int startIndex, int length, @ConstantParameter Register threadRegister) {
+    public static void g1ArrayRangePreWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) {
         Word thread = registerAsWord(threadRegister);
         byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG));
         // If the concurrent marker is not enabled or the vector length is zero, return.
         if (markingValue == (byte) 0 || length == 0) {
             return;
         }
-        Object dest = FixedValueAnchorNode.getObject(object);
         Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG));
         Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG));
-        long dstAddr = GetObjectAddressNode.get(dest);
         long indexValue = indexAddress.readWord(0).rawValue();
         final int scale = arrayIndexScale(JavaKind.Object);
-        int header = arrayBaseOffset(JavaKind.Object);
+        long start = getPointerToFirstArrayElement(address, length, elementStride);
 
-        for (int i = startIndex; i < length; i++) {
-            Word address = WordFactory.pointer(dstAddr + header + (i * scale));
-            Pointer oop = Word.objectToTrackedPointer(address.readObject(0, BarrierType.NONE));
+        for (int i = 0; i < length; i++) {
+            Word arrElemPtr = WordFactory.pointer(start + i * scale);
+            Pointer oop = Word.objectToTrackedPointer(arrElemPtr.readObject(0, BarrierType.NONE));
             verifyOop(oop.toObject());
             if (oop.notEqual(0)) {
                 if (indexValue != 0) {
@@ -339,11 +331,10 @@
     }
 
     @Snippet
-    public static void g1ArrayRangePostWriteBarrier(Object object, int startIndex, int length, @ConstantParameter Register threadRegister) {
+    public static void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) {
         if (length == 0) {
             return;
         }
-        Object dest = FixedValueAnchorNode.getObject(object);
         Word thread = registerAsWord(threadRegister);
         Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG));
         Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
@@ -351,11 +342,8 @@
 
         int cardShift = cardTableShift(INJECTED_VMCONFIG);
         final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress();
-        final int scale = arrayIndexScale(JavaKind.Object);
-        int header = arrayBaseOffset(JavaKind.Object);
-        long dstAddr = GetObjectAddressNode.get(dest);
-        long start = (dstAddr + header + (long) startIndex * scale) >>> cardShift;
-        long end = (dstAddr + header + ((long) startIndex + length - 1) * scale) >>> cardShift;
+        long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift;
+        long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift;
         long count = end - start + 1;
 
         while (count-- > 0) {
@@ -384,6 +372,26 @@
         }
     }
 
+    private static long getPointerToFirstArrayElement(Address address, int length, int elementStride) {
+        long result = Word.fromAddress(address).rawValue();
+        if (elementStride < 0) {
+            // the address points to the place after the last array element
+            result = result + elementStride * length;
+        }
+        return result;
+    }
+
+    private static long getPointerToLastArrayElement(Address address, int length, int elementStride) {
+        long result = Word.fromAddress(address).rawValue();
+        if (elementStride < 0) {
+            // the address points to the place after the last array element
+            result = result + elementStride;
+        } else {
+            result = result + (length - 1) * elementStride;
+        }
+        return result;
+    }
+
     public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class);
 
     @NodeIntrinsic(ForeignCallNode.class)
@@ -431,9 +439,9 @@
 
         public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, LoweringTool tool) {
             Arguments args = new Arguments(serialArrayRangeWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("object", arrayRangeWriteBarrier.getObject());
-            args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
+            args.add("address", arrayRangeWriteBarrier.getAddress());
             args.add("length", arrayRangeWriteBarrier.getLength());
+            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
             template(arrayRangeWriteBarrier.getDebug(), args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
@@ -519,18 +527,18 @@
 
         public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) {
             Arguments args = new Arguments(g1ArrayRangePreWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("object", arrayRangeWriteBarrier.getObject());
-            args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
+            args.add("address", arrayRangeWriteBarrier.getAddress());
             args.add("length", arrayRangeWriteBarrier.getLength());
+            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
             args.addConst("threadRegister", registers.getThreadRegister());
             template(arrayRangeWriteBarrier.getDebug(), args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) {
             Arguments args = new Arguments(g1ArrayRangePostWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("object", arrayRangeWriteBarrier.getObject());
-            args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
+            args.add("address", arrayRangeWriteBarrier.getAddress());
             args.add("length", arrayRangeWriteBarrier.getLength());
+            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
             args.addConst("threadRegister", registers.getThreadRegister());
             template(arrayRangeWriteBarrier.getDebug(), args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Fri Feb 02 17:28:17 2018 -0800
@@ -40,6 +40,7 @@
 import java.lang.reflect.Method;
 import java.util.EnumMap;
 
+import org.graalvm.collections.UnmodifiableEconomicMap;
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.api.replacements.Fold;
 import org.graalvm.compiler.api.replacements.Snippet;
@@ -76,7 +77,6 @@
 import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
 import org.graalvm.compiler.word.Word;
-import org.graalvm.util.UnmodifiableEconomicMap;
 import org.graalvm.word.LocationIdentity;
 import org.graalvm.word.WordFactory;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Fri Feb 02 17:28:17 2018 -0800
@@ -34,6 +34,21 @@
 import java.util.ListIterator;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.site.Call;
+import jdk.vm.ci.code.site.ConstantReference;
+import jdk.vm.ci.code.site.DataPatch;
+import jdk.vm.ci.code.site.Infopoint;
+import jdk.vm.ci.hotspot.HotSpotCompiledCode;
+import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
+import jdk.vm.ci.meta.DefaultProfilingInfo;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.TriState;
+
+import org.graalvm.collections.EconomicSet;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.target.Backend;
@@ -54,21 +69,6 @@
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.tiers.Suites;
 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
-import org.graalvm.util.EconomicSet;
-
-import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.RegisterConfig;
-import jdk.vm.ci.code.site.Call;
-import jdk.vm.ci.code.site.ConstantReference;
-import jdk.vm.ci.code.site.DataPatch;
-import jdk.vm.ci.code.site.Infopoint;
-import jdk.vm.ci.hotspot.HotSpotCompiledCode;
-import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
-import jdk.vm.ci.meta.DefaultProfilingInfo;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.TriState;
 
 //JaCoCo Exclude
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Fri Feb 02 17:28:17 2018 -0800
@@ -86,6 +86,8 @@
 import java.util.List;
 import java.util.TreeSet;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeLookupSwitch;
 import org.graalvm.compiler.bytecode.BytecodeStream;
@@ -95,8 +97,6 @@
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.ExceptionHandler;
@@ -415,9 +415,6 @@
     }
 
     public static class ExceptionDispatchBlock extends BciBlock {
-
-        private EconomicMap<ExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = EconomicMap.create(Equivalence.DEFAULT);
-
         public ExceptionHandler handler;
         public int deoptBci;
     }
@@ -748,15 +745,6 @@
         }
     }
 
-    private EconomicMap<ExceptionHandler, ExceptionDispatchBlock> initialExceptionDispatch;
-
-    private EconomicMap<ExceptionHandler, ExceptionDispatchBlock> getInitialExceptionDispatch() {
-        if (initialExceptionDispatch == null) {
-            initialExceptionDispatch = EconomicMap.create(Equivalence.DEFAULT);
-        }
-        return initialExceptionDispatch;
-    }
-
     private ExceptionDispatchBlock handleExceptions(BciBlock[] blockMap, int bci) {
         ExceptionDispatchBlock lastHandler = null;
 
@@ -769,20 +757,17 @@
                     lastHandler = null;
                 }
 
-                EconomicMap<ExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = lastHandler != null ? lastHandler.exceptionDispatch : getInitialExceptionDispatch();
-                ExceptionDispatchBlock curHandler = exceptionDispatch.get(h);
-                if (curHandler == null) {
-                    curHandler = new ExceptionDispatchBlock();
-                    blocksNotYetAssignedId++;
-                    curHandler.startBci = -1;
-                    curHandler.endBci = -1;
-                    curHandler.deoptBci = bci;
-                    curHandler.handler = h;
-                    curHandler.addSuccessor(blockMap[h.getHandlerBCI()]);
-                    if (lastHandler != null) {
-                        curHandler.addSuccessor(lastHandler);
-                    }
-                    exceptionDispatch.put(h, curHandler);
+                // 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;
+                curHandler.addSuccessor(blockMap[h.getHandlerBCI()]);
+                if (lastHandler != null) {
+                    curHandler.addSuccessor(lastHandler);
                 }
                 lastHandler = curHandler;
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Feb 02 17:28:17 2018 -0800
@@ -265,6 +265,8 @@
 import java.util.Formatter;
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeDisassembler;
@@ -278,9 +280,12 @@
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.calc.Condition;
+import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
 import org.graalvm.compiler.core.common.calc.FloatConvert;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
@@ -343,8 +348,8 @@
 import org.graalvm.compiler.nodes.calc.AndNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
+import org.graalvm.compiler.nodes.calc.FloatConvertNode;
 import org.graalvm.compiler.nodes.calc.FloatDivNode;
-import org.graalvm.compiler.nodes.calc.FloatConvertNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
@@ -408,8 +413,6 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.util.ValueMergeUtil;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.code.BailoutException;
@@ -436,7 +439,6 @@
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Signature;
 import jdk.vm.ci.meta.TriState;
-import org.graalvm.compiler.core.common.type.IntegerStamp;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -577,10 +579,11 @@
                             // value on the stack on entry to an exception handler,
                             // namely the exception object.
                             assert frameState.rethrowException();
-                            ExceptionObjectNode exceptionObject = (ExceptionObjectNode) frameState.stackAt(0);
+                            ValueNode exceptionValue = frameState.stackAt(0);
+                            ExceptionObjectNode exceptionObject = (ExceptionObjectNode) GraphUtil.unproxify(exceptionValue);
                             FrameStateBuilder dispatchState = parser.frameState.copy();
                             dispatchState.clearStack();
-                            dispatchState.push(JavaKind.Object, exceptionObject);
+                            dispatchState.push(JavaKind.Object, exceptionValue);
                             dispatchState.setRethrowException(true);
                             FrameState newFrameState = dispatchState.create(parser.bci(), exceptionObject);
                             frameState.replaceAndDelete(newFrameState);
@@ -700,6 +703,12 @@
 
         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;
@@ -1893,7 +1902,7 @@
             LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
             LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
             ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
-            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
+            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
 
             JavaTypeProfile profile = null;
             if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@@ -2267,8 +2276,10 @@
     }
 
     protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
+        FixedWithNextNode calleeBeforeUnwindNode = null;
+        ValueNode calleeUnwindValue = null;
+
         try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
-
             BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
             FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
             if (!targetMethod.isStatic()) {
@@ -2315,13 +2326,25 @@
                 }
             }
 
-            FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
+            calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
             if (calleeBeforeUnwindNode != null) {
-                ValueNode calleeUnwindValue = parser.getUnwindValue();
+                calleeUnwindValue = parser.getUnwindValue();
                 assert calleeUnwindValue != null;
-                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
             }
         }
+
+        /*
+         * Method handleException will call createTarget, which wires this exception edge to the
+         * corresponding exception dispatch block in the caller. In the case where it wires to the
+         * caller's unwind block, any FrameState created meanwhile, e.g., FrameState for
+         * LoopExitNode, would be instantiated with AFTER_EXCEPTION_BCI. Such frame states should
+         * not be fixed by IntrinsicScope.close, as they denote the states of the caller. Thus, the
+         * following code should be placed outside the IntrinsicScope, so that correctly created
+         * FrameStates are not replaced.
+         */
+        if (calleeBeforeUnwindNode != null) {
+            calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
+        }
     }
 
     public MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, JavaTypeProfile profile) {
@@ -2773,6 +2796,10 @@
             setCurrentFrameState(frameState);
             currentBlock = block;
 
+            if (block != blockMap.getUnwindBlock() && !(block instanceof ExceptionDispatchBlock)) {
+                frameState.setRethrowException(false);
+            }
+
             if (firstInstruction instanceof AbstractMergeNode) {
                 setMergeStateAfter(block, firstInstruction);
             }
@@ -2782,7 +2809,6 @@
             } else if (block instanceof ExceptionDispatchBlock) {
                 createExceptionDispatch((ExceptionDispatchBlock) block);
             } else {
-                frameState.setRethrowException(false);
                 iterateBytecodesForBlock(block);
             }
         }
@@ -3055,7 +3081,7 @@
     }
 
     private boolean traceState() {
-        if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
+        if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
             frameState.traceState();
         }
         return true;
@@ -3075,56 +3101,107 @@
 
         ValueNode a = x;
         ValueNode b = y;
+        BciBlock trueSuccessor = trueBlock;
+        BciBlock falseSuccessor = falseBlock;
+
+        CanonicalizedCondition canonicalizedCondition = cond.canonicalize();
 
         // Check whether the condition needs to mirror the operands.
-        if (cond.canonicalMirror()) {
+        if (canonicalizedCondition.mustMirror()) {
             a = y;
             b = x;
         }
+        if (canonicalizedCondition.mustNegate()) {
+            trueSuccessor = falseBlock;
+            falseSuccessor = trueBlock;
+        }
 
         // Create the logic node for the condition.
-        LogicNode condition = createLogicNode(cond, a, b);
-
-        // Check whether the condition needs to negate the result.
-        boolean negate = cond.canonicalNegate();
-        genIf(condition, negate, trueBlock, falseBlock);
-    }
-
-    protected void genIf(LogicNode conditionInput, boolean negateCondition, BciBlock trueBlockInput, BciBlock falseBlockInput) {
+        LogicNode condition = createLogicNode(canonicalizedCondition.getCanonicalCondition(), a, b);
+
+        double probability = -1;
+        if (condition instanceof IntegerEqualsNode) {
+            probability = extractInjectedProbability((IntegerEqualsNode) condition);
+            // the probability coming from here is about the actual condition
+        }
+
+        if (probability == -1) {
+            probability = getProfileProbability(canonicalizedCondition.mustNegate());
+        }
+
+        probability = clampProbability(probability);
+        genIf(condition, trueSuccessor, falseSuccessor, probability);
+    }
+
+    private double getProfileProbability(boolean negate) {
+        double probability;
+        if (profilingInfo == null) {
+            probability = 0.5;
+        } else {
+            assert assertAtIfBytecode();
+            probability = profilingInfo.getBranchTakenProbability(bci());
+            if (probability < 0) {
+                assert probability == -1 : "invalid probability";
+                debug.log("missing probability in %s at bci %d", code, bci());
+                probability = 0.5;
+            } else {
+                if (negate) {
+                    // the probability coming from profile is about the original condition
+                    probability = 1 - probability;
+                }
+            }
+        }
+        return probability;
+    }
+
+    private static double extractInjectedProbability(IntegerEqualsNode condition) {
+        // Propagate injected branch probability if any.
+        IntegerEqualsNode equalsNode = condition;
+        BranchProbabilityNode probabilityNode = null;
+        ValueNode other = null;
+        if (equalsNode.getX() instanceof BranchProbabilityNode) {
+            probabilityNode = (BranchProbabilityNode) equalsNode.getX();
+            other = equalsNode.getY();
+        } else if (equalsNode.getY() instanceof BranchProbabilityNode) {
+            probabilityNode = (BranchProbabilityNode) equalsNode.getY();
+            other = equalsNode.getX();
+        }
+
+        if (probabilityNode != null && probabilityNode.getProbability().isConstant() && other != null && other.isConstant()) {
+            double probabilityValue = probabilityNode.getProbability().asJavaConstant().asDouble();
+            return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
+        }
+        return -1;
+    }
+
+    protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
         BciBlock trueBlock = trueBlockInput;
         BciBlock falseBlock = falseBlockInput;
         LogicNode condition = conditionInput;
+        double probability = probabilityInput;
         FrameState stateBefore = null;
         ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
         if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
             stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
         }
 
-        // Remove a logic negation node and fold it into the negate boolean.
-        boolean negate = negateCondition;
+        // Remove a logic negation node.
         if (condition instanceof LogicNegationNode) {
             LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
-            negate = !negate;
+            BciBlock tmpBlock = trueBlock;
+            trueBlock = falseBlock;
+            falseBlock = tmpBlock;
+            probability = 1 - probability;
             condition = logicNegationNode.getValue();
         }
 
         if (condition instanceof LogicConstantNode) {
-            genConstantTargetIf(trueBlock, falseBlock, negate, condition);
+            genConstantTargetIf(trueBlock, falseBlock, condition);
         } else {
             if (condition.graph() == null) {
                 condition = genUnique(condition);
             }
 
-            // Need to get probability based on current bci.
-            double probability = branchProbability(condition);
-
-            if (negate) {
-                BciBlock tmpBlock = trueBlock;
-                trueBlock = falseBlock;
-                falseBlock = tmpBlock;
-                probability = 1 - probability;
-            }
-
             if (isNeverExecutedCode(probability)) {
                 append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
                 if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
@@ -3200,28 +3277,26 @@
         }
     }
 
-    private LogicNode createLogicNode(Condition cond, ValueNode a, ValueNode b) {
-        LogicNode condition;
+    private LogicNode createLogicNode(CanonicalCondition cond, ValueNode a, ValueNode b) {
         assert !a.getStackKind().isNumericFloat();
-        if (cond == Condition.EQ || cond == Condition.NE) {
-            if (a.getStackKind() == JavaKind.Object) {
-                condition = genObjectEquals(a, b);
-            } else {
-                condition = genIntegerEquals(a, b);
-            }
-        } else {
-            assert a.getStackKind() != JavaKind.Object && !cond.isUnsigned();
-            condition = genIntegerLessThan(a, b);
+        switch (cond) {
+            case EQ:
+                if (a.getStackKind() == JavaKind.Object) {
+                    return genObjectEquals(a, b);
+                } else {
+                    return genIntegerEquals(a, b);
+                }
+            case LT:
+                assert a.getStackKind() != JavaKind.Object;
+                return genIntegerLessThan(a, b);
+            default:
+                throw GraalError.shouldNotReachHere("Unexpected condition: " + cond);
         }
-        return condition;
-    }
-
-    private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, boolean negate, LogicNode condition) {
+    }
+
+    private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, LogicNode condition) {
         LogicConstantNode constantLogicNode = (LogicConstantNode) condition;
         boolean value = constantLogicNode.getValue();
-        if (negate) {
-            value = !value;
-        }
         BciBlock nextBlock = falseBlock;
         if (value) {
             nextBlock = trueBlock;
@@ -3775,7 +3850,13 @@
             BciBlock firstSucc = currentBlock.getSuccessor(0);
             BciBlock secondSucc = currentBlock.getSuccessor(1);
             if (firstSucc != secondSucc) {
-                genIf(instanceOfNode, value != Bytecodes.IFNE, firstSucc, secondSucc);
+                boolean negate = value != Bytecodes.IFNE;
+                if (negate) {
+                    BciBlock tmp = firstSucc;
+                    firstSucc = secondSucc;
+                    secondSucc = tmp;
+                }
+                genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
             } else {
                 appendGoto(firstSucc);
             }
@@ -4263,47 +4344,12 @@
         return probability == 0 && optimisticOpts.removeNeverExecutedCode(getOptions());
     }
 
-    private double rawBranchProbability(LogicNode conditionInput) {
-        if (conditionInput instanceof IntegerEqualsNode) {
-            // Propagate injected branch probability if any.
-            IntegerEqualsNode condition = (IntegerEqualsNode) conditionInput;
-            BranchProbabilityNode injectedProbability = null;
-            ValueNode other = null;
-            if (condition.getX() instanceof BranchProbabilityNode) {
-                injectedProbability = (BranchProbabilityNode) condition.getX();
-                other = condition.getY();
-            } else if (condition.getY() instanceof BranchProbabilityNode) {
-                injectedProbability = (BranchProbabilityNode) condition.getY();
-                other = condition.getX();
-            }
-
-            if (injectedProbability != null && injectedProbability.getProbability().isConstant() && other != null && other.isConstant()) {
-                double probabilityValue = injectedProbability.getProbability().asJavaConstant().asDouble();
-                return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
-            }
-        }
-
-        if (profilingInfo == null) {
-            return 0.5;
-        }
-        assert assertAtIfBytecode();
-
-        return profilingInfo.getBranchTakenProbability(bci());
-    }
-
-    protected double branchProbability(LogicNode conditionInput) {
-        double probability = rawBranchProbability(conditionInput);
-        if (probability < 0) {
-            assert probability == -1 : "invalid probability";
-            debug.log("missing probability in %s at bci %d", code, bci());
-            probability = 0.5;
-        }
-
+    private double clampProbability(double probability) {
         if (!optimisticOpts.removeNeverExecutedCode(getOptions())) {
             if (probability == 0) {
-                probability = 0.0000001;
+                return 0.0000001;
             } else if (probability == 1) {
-                probability = 0.999999;
+                return 0.999999;
             }
         }
         return probability;
@@ -4568,7 +4614,7 @@
     }
 
     protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
-        if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
+        if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
             traceInstructionHelper(bci, opcode, blockStart);
         }
         return true;
@@ -4589,7 +4635,7 @@
         if (!currentBlock.getJsrScope().isEmpty()) {
             sb.append(' ').append(currentBlock.getJsrScope());
         }
-        debug.log("%s", sb);
+        TTY.println("%s", sb);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Fri Feb 02 17:28:17 2018 -0800
@@ -34,7 +34,9 @@
  */
 public class BytecodeParserOptions {
     // @formatter:off
-    @Option(help = "The trace level for the bytecode parser used when building a graph from bytecode", type = OptionType.Debug)
+    @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)
     public static final OptionKey<Integer> TraceBytecodeParserLevel = new OptionKey<>(0);
 
     @Option(help = "Inlines trivial methods during bytecode parsing.", type = OptionType.Expert)
@@ -56,7 +58,7 @@
     public static final OptionKey<Boolean> TraceParserPlugins = new OptionKey<>(false);
 
     @Option(help = "Maximum depth when inlining during bytecode parsing.", type = OptionType.Debug)
-    public static final OptionKey<Integer> InlineDuringParsingMaxDepth = new OptionKey<>(10);
+    public static final OptionKey<Integer> InlineDuringParsingMaxDepth = new OptionKey<>(3);
 
     @Option(help = "When creating info points hide the methods of the substitutions.", type = OptionType.Debug)
     public static final OptionKey<Boolean> HideSubstitutionStates = new OptionKey<>(false);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/ComputeLoopFrequenciesClosure.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/ComputeLoopFrequenciesClosure.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,8 +22,11 @@
  */
 package org.graalvm.compiler.java;
 
+import static org.graalvm.compiler.nodes.cfg.ControlFlowGraph.multiplyProbabilities;
+
 import java.util.List;
 
+import org.graalvm.collections.EconomicMap;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.ControlSplitNode;
@@ -34,9 +37,6 @@
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
 import org.graalvm.compiler.phases.Phase;
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
-import org.graalvm.util.EconomicMap;
-
-import static org.graalvm.compiler.nodes.cfg.ControlFlowGraph.multiplyProbabilities;
 
 public final class ComputeLoopFrequenciesClosure extends ReentrantNodeIterator.NodeIteratorClosure<Double> {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Fri Feb 02 17:28:17 2018 -0800
@@ -47,6 +47,7 @@
 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;
@@ -999,15 +1000,14 @@
     }
 
     public void traceState() {
-        DebugContext debug = graph.getDebug();
-        debug.log("|   state [nr locals = %d, stack depth = %d, method = %s]", localsSize(), stackSize(), getMethod());
+        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];
-            debug.log("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
+            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];
-            debug.log("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
+            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.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayEqualsOp.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayEqualsOp.java	Fri Feb 02 17:28:17 2018 -0800
@@ -26,9 +26,6 @@
 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.AArch64Assembler.ConditionFlag;
@@ -43,7 +40,6 @@
 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 of the same length. If the CPU supports any vector
@@ -72,9 +68,8 @@
         assert !kind.isNumericFloat() : "Float arrays comparison (bitwise_equal || both_NaN) isn't supported";
         this.kind = kind;
 
-        Class<?> arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass();
-        this.arrayBaseOffset = UNSAFE.arrayBaseOffset(arrayClass);
-        this.arrayIndexScale = UNSAFE.arrayIndexScale(arrayClass);
+        this.arrayBaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind);
+        this.arrayIndexScale = tool.getProviders().getArrayOffsetProvider().arrayScalingFactor(kind);
 
         this.resultValue = result;
         this.array1Value = array1;
@@ -218,20 +213,4 @@
         masm.bind(end);
         masm.mov(64, rscratch1, zr);
     }
-
-    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);
-            }
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Fri Feb 02 17:28:17 2018 -0800
@@ -22,12 +22,9 @@
  */
 package org.graalvm.compiler.lir.amd64;
 
+import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
 
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
@@ -50,7 +47,6 @@
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
-import sun.misc.Unsafe;
 
 /**
  * Emits code which compares two arrays of the same length. If the CPU supports any vector
@@ -83,9 +79,8 @@
         super(TYPE);
         this.kind = kind;
 
-        Class<?> arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass();
-        this.arrayBaseOffset = UNSAFE.arrayBaseOffset(arrayClass);
-        this.arrayIndexScale = UNSAFE.arrayIndexScale(arrayClass);
+        this.arrayBaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind);
+        this.arrayIndexScale = tool.getProviders().getArrayOffsetProvider().arrayScalingFactor(kind);
 
         this.resultValue = result;
         this.array1Value = array1;
@@ -531,20 +526,4 @@
         // Floats within the range are equal, revert change to the register index
         masm.subq(index, range);
     }
-
-    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);
-            }
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Call.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Call.java	Fri Feb 02 17:28:17 2018 -0800
@@ -101,6 +101,10 @@
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             directCall(crb, masm, callTarget, null, true, state);
         }
+
+        public int emitCall(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            return directCall(crb, masm, callTarget, null, true, state);
+        }
     }
 
     @Opcode("CALL_INDIRECT")
@@ -183,23 +187,27 @@
         }
     }
 
-    public static void directCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
+    public static int directCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
         if (align) {
             emitAlignmentForDirectCall(crb, masm);
         }
         int before = masm.position();
+        int callPCOffset;
         if (scratch != null) {
             // offset might not fit a 32-bit immediate, generate an
             // indirect call with a 64-bit immediate
             masm.movq(scratch, 0L);
+            callPCOffset = masm.position();
             masm.call(scratch);
         } else {
+            callPCOffset = masm.position();
             masm.call();
         }
         int after = masm.position();
         crb.recordDirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
+        return callPCOffset;
     }
 
     protected static void emitAlignmentForDirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
@@ -228,12 +236,13 @@
         masm.ensureUniquePC();
     }
 
-    public static void indirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
+    public static int indirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.position();
         masm.call(dst);
         int after = masm.position();
         crb.recordIndirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
+        return before;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Fri Feb 02 17:28:17 2018 -0800
@@ -25,6 +25,7 @@
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag.Equal;
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
@@ -755,17 +756,18 @@
         }
     }
 
-    public abstract static class Pointer extends AMD64LIRInstruction {
+    public abstract static class PointerCompressionOp extends AMD64LIRInstruction {
         protected final LIRKindTool lirKindTool;
         protected final CompressEncoding encoding;
         protected final boolean nonNull;
 
         @Def({REG, HINT}) private AllocatableValue result;
-        @Use({REG}) private AllocatableValue input;
+        @Use({REG, CONST}) private Value input;
         @Alive({REG, ILLEGAL}) private AllocatableValue baseRegister;
 
-        protected Pointer(LIRInstructionClass<? extends Pointer> type, AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull,
-                        LIRKindTool lirKindTool) {
+        protected PointerCompressionOp(LIRInstructionClass<? extends PointerCompressionOp> type, AllocatableValue result, Value input,
+                        AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+
             super(type);
             this.result = result;
             this.input = input;
@@ -779,8 +781,12 @@
             return GeneratePIC.getValue(crb.getOptions()) || encoding.hasBase();
         }
 
-        protected final Register getResultRegister() {
-            return asRegister(result);
+        public fina