# HG changeset patch # User iveresov # Date 1503960356 0 # Node ID eb64593343998b906a4195e4bb0d8adf00f0433a # Parent 4a770830380704431b5ec5cc52e495800397458d# Parent 630d326a3d15b881743672163621ee350532e346 Merge diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java --- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Mon Aug 28 22:45:56 2017 +0000 @@ -187,10 +187,9 @@ {"StubRoutines::_arrayof_oop_disjoint_arraycopy", "_aot_stub_routines_arrayof_oop_disjoint_arraycopy"}, {"StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit", "_aot_stub_routines_arrayof_oop_disjoint_arraycopy_uninit"}, - {"StubRoutines::_checkcast_arraycopy", "_aot_stub_routines_checkcast_arraycopy"}, + {"StubRoutines::_unsafe_arraycopy", "_aot_stub_routines_unsafe_arraycopy"}, - - + {"StubRoutines::_checkcast_arraycopy", "_aot_stub_routines_checkcast_arraycopy"}, {"StubRoutines::_aescrypt_encryptBlock", "_aot_stub_routines_aescrypt_encryptBlock"}, {"StubRoutines::_aescrypt_decryptBlock", "_aot_stub_routines_aescrypt_decryptBlock"}, @@ -478,8 +477,8 @@ } /** - * Creates a global symbol of the form {@code "A" + container name}. - * Note, linker on Windows does not allow names which start with '.' + * Creates a global symbol of the form {@code "A" + container name}. Note, linker on Windows + * does not allow names which start with '.' * * @param container container to create a symbol for */ @@ -685,7 +684,8 @@ } /** - * Add oop symbol by as follows. Extend the oop.got section with another slot for the VM to patch. + * Add oop symbol by as follows. Extend the oop.got section with another slot for the VM to + * patch. * * @param oopName name of the oop symbol */ @@ -728,10 +728,9 @@ } /** - * Add klass symbol by as follows. - * - Adding the symbol name to the metaspace.names section - * - Add the offset of the name in metaspace.names to metaspace.offsets - * - Extend the klasses.got section with another slot for the VM to patch + * Add klass symbol by as follows. - Adding the symbol name to the metaspace.names section - Add + * the offset of the name in metaspace.names to metaspace.offsets - Extend the klasses.got + * section with another slot for the VM to patch * * @param klassName name of the metaspace symbol * @return the got offset in the klasses.got of the metaspace symbol diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java --- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Mon Aug 28 22:45:56 2017 +0000 @@ -27,6 +27,8 @@ import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.GraalCompiler; +import org.graalvm.compiler.core.common.CompilationIdentifier; +import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder; @@ -127,7 +129,13 @@ ProfilingInfo profilingInfo = DefaultProfilingInfo.get(TriState.FALSE); final boolean isImmutablePIC = true; - CompilationResult compilationResult = new CompilationResult(resolvedMethod.getName(), isImmutablePIC); + CompilationIdentifier id = new CompilationIdentifier() { + @Override + public String toString(Verbosity verbosity) { + return resolvedMethod.getName(); + } + }; + CompilationResult compilationResult = new CompilationResult(id, isImmutablePIC); return GraalCompiler.compileGraph(graph, resolvedMethod, providers, backend, graphBuilderSuite, OptimisticOptimizations.ALL, profilingInfo, getSuites(), getLirSuites(), compilationResult, CompilationResultBuilderFactory.Default); diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/ClassSubstitution.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/ClassSubstitution.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/ClassSubstitution.java Mon Aug 28 22:45:56 2017 +0000 @@ -57,7 +57,9 @@ /** * Determines if the substitutions are for classes that may not be part of the runtime. - * Substitutions for such classes are omitted if the original classes cannot be found. + * Substitutions for such classes are omitted if the original classes cannot be found. If + * multiple classes are specified using {@link #className()} and {@link #optional()} is false, + * then at least one of the classes is required to be reachable. */ boolean optional() default false; } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.test/src/org/graalvm/compiler/asm/test/AssemblerTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.test/src/org/graalvm/compiler/asm/test/AssemblerTest.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.test/src/org/graalvm/compiler/asm/test/AssemblerTest.java Mon Aug 28 22:45:56 2017 +0000 @@ -90,7 +90,7 @@ StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).compilationId(compilationId).build(); CallingConvention cc = backend.newLIRGenerationResult(compilationId, null, null, graph, null).getCallingConvention(); - CompilationResult compResult = new CompilationResult(); + CompilationResult compResult = new CompilationResult(graph.compilationId()); byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc); compResult.setTargetCode(targetCode, targetCode.length); compResult.setTotalFrameSize(0); diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java Mon Aug 28 22:45:56 2017 +0000 @@ -33,6 +33,7 @@ import java.util.List; import java.util.Objects; +import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.util.EconomicSet; @@ -190,6 +191,8 @@ private final String name; + private final CompilationIdentifier compilationId; + /** * The buffer containing the emitted machine code. */ @@ -222,21 +225,26 @@ private boolean isImmutablePIC; - public CompilationResult() { - this(null, false); + public CompilationResult(CompilationIdentifier compilationId) { + this(compilationId, compilationId.toString(CompilationIdentifier.Verbosity.NAME), false); + } + + public CompilationResult(CompilationIdentifier compilationId, String name) { + this(compilationId, name, false); + } + + public CompilationResult(CompilationIdentifier compilationId, boolean isImmutablePIC) { + this(compilationId, null, isImmutablePIC); + } + + public CompilationResult(CompilationIdentifier compilationId, String name, boolean isImmutablePIC) { + this.compilationId = compilationId; + this.name = name; + this.isImmutablePIC = isImmutablePIC; } public CompilationResult(String name) { - this(name, false); - } - - public CompilationResult(boolean isImmutablePIC) { - this(null, isImmutablePIC); - } - - public CompilationResult(String name, boolean isImmutablePIC) { - this.name = name; - this.isImmutablePIC = isImmutablePIC; + this(null, name); } @Override @@ -266,6 +274,7 @@ this.totalFrameSize == that.totalFrameSize && this.targetCodeSize == that.targetCodeSize && Objects.equals(this.name, that.name) && + Objects.equals(this.compilationId, that.compilationId) && Objects.equals(this.annotations, that.annotations) && Objects.equals(this.dataSection, that.dataSection) && Objects.equals(this.exceptionHandlers, that.exceptionHandlers) && @@ -670,6 +679,10 @@ return name; } + public CompilationIdentifier getCompilationId() { + return compilationId; + } + public void setHasUnsafeAccess(boolean hasUnsafeAccess) { checkOpen(); this.hasUnsafeAccess = hasUnsafeAccess; diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Mon Aug 28 22:45:56 2017 +0000 @@ -949,7 +949,7 @@ try (AllocSpy spy = AllocSpy.open(installedCodeOwner); DebugContext.Scope ds = debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) { CompilationPrinter printer = CompilationPrinter.begin(options, id, installedCodeOwner, INVOCATION_ENTRY_BCI); - CompilationResult compResult = compile(installedCodeOwner, graphToCompile, new CompilationResult(), id, options); + CompilationResult compResult = compile(installedCodeOwner, graphToCompile, new CompilationResult(graphToCompile.compilationId()), id, options); printer.finish(compResult); try (DebugContext.Scope s = debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult); @@ -1019,17 +1019,19 @@ */ protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) { OptionValues options = graph == null ? getInitialOptions() : graph.getOptions(); - return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options); + CompilationIdentifier compilationId = getOrCreateCompilationId(installedCodeOwner, graph); + return compile(installedCodeOwner, graph, new CompilationResult(compilationId), compilationId, options); } protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationIdentifier compilationId) { OptionValues options = graph == null ? getInitialOptions() : graph.getOptions(); - return compile(installedCodeOwner, graph, new CompilationResult(), compilationId, options); + return compile(installedCodeOwner, graph, new CompilationResult(compilationId), compilationId, options); } protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, OptionValues options) { assert graph == null || graph.getOptions() == options; - return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options); + CompilationIdentifier compilationId = getOrCreateCompilationId(installedCodeOwner, graph); + return compile(installedCodeOwner, graph, new CompilationResult(compilationId), compilationId, options); } /** diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InfopointReasonTest.java Mon Aug 28 22:45:56 2017 +0000 @@ -64,7 +64,7 @@ final ResolvedJavaMethod method = getResolvedJavaMethod("testMethod"); final StructuredGraph graph = parseEager(method, AllowAssumptions.YES); final CompilationResult cr = compileGraph(graph, graph.method(), getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, graph.getProfilingInfo(), - createSuites(graph.getOptions()), createLIRSuites(graph.getOptions()), new CompilationResult(), CompilationResultBuilderFactory.Default); + createSuites(graph.getOptions()), createLIRSuites(graph.getOptions()), new CompilationResult(graph.compilationId()), CompilationResultBuilderFactory.Default); for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); if (sp instanceof Call) { @@ -86,7 +86,7 @@ assertTrue(graphLineSPs > 0); PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true)); final CompilationResult cr = compileGraph(graph, graph.method(), getProviders(), getBackend(), graphBuilderSuite, OptimisticOptimizations.ALL, graph.getProfilingInfo(), - createSuites(graph.getOptions()), createLIRSuites(graph.getOptions()), new CompilationResult(), CompilationResultBuilderFactory.Default); + createSuites(graph.getOptions()), createLIRSuites(graph.getOptions()), new CompilationResult(graph.compilationId()), CompilationResultBuilderFactory.Default); int lineSPs = 0; for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java Mon Aug 28 22:45:56 2017 +0000 @@ -123,7 +123,7 @@ ProfilingInfo profilingInfo = graph.getProfilingInfo(method); /* The default class and configuration for compilation results. */ - CompilationResult compilationResult = new CompilationResult(); + CompilationResult compilationResult = new CompilationResult(graph.compilationId()); CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default; /* Invoke the whole Graal compilation pipeline. */ diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/NodeBitMapTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/NodeBitMapTest.java Mon Aug 28 22:45:56 2017 +0000 @@ -0,0 +1,203 @@ +/* + * 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.graph.test; + +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.graalvm.compiler.api.test.Graal; +import org.graalvm.compiler.graph.Graph; +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.graph.NodeBitMap; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.options.OptionValues; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class NodeBitMapTest extends GraphTest { + + @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) + static final class TestNode extends Node { + public static final NodeClass TYPE = NodeClass.create(TestNode.class); + + protected TestNode() { + super(TYPE); + } + } + + private Graph graph; + private TestNode[] nodes = new TestNode[100]; + private NodeBitMap map; + + @Before + public void before() { + // Need to initialize HotSpotGraalRuntime before any Node class is initialized. + Graal.getRuntime(); + + OptionValues options = getOptions(); + graph = new Graph(options, getDebug(options)); + for (int i = 0; i < nodes.length; i++) { + nodes[i] = graph.add(new TestNode()); + } + map = graph.createNodeBitMap(); + } + + @Test + public void iterateEmpty() { + for (Node n : map) { + Assert.fail("no elements expected: " + n); + } + } + + @Test + public void iterateMarkedNodes() { + map.mark(nodes[99]); + map.mark(nodes[0]); + map.mark(nodes[7]); + map.mark(nodes[1]); + map.mark(nodes[53]); + + Iterator iter = map.iterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[0], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[1], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[7], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[53], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[99], iter.next()); + Assert.assertFalse(iter.hasNext()); + } + + @Test + public void deleteNodeWhileIterating() { + map.mark(nodes[99]); + map.mark(nodes[0]); + map.mark(nodes[7]); + map.mark(nodes[1]); + map.mark(nodes[53]); + + Iterator iter = map.iterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[0], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[1], iter.next()); + nodes[7].markDeleted(); + nodes[53].markDeleted(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[99], iter.next()); + Assert.assertFalse(iter.hasNext()); + } + + @Test + public void deleteAllNodesBeforeIterating() { + for (int i = 0; i < nodes.length; i++) { + map.mark(nodes[i]); + nodes[i].markDeleted(); + } + + Iterator iter = map.iterator(); + Assert.assertFalse(iter.hasNext()); + } + + @Test + public void multipleHasNextInvocations() { + map.mark(nodes[7]); + + Iterator iter = map.iterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[7], iter.next()); + Assert.assertFalse(iter.hasNext()); + } + + @Test(expected = NoSuchElementException.class) + public void noSuchElement() { + map.iterator().next(); + } + + @Test(expected = ConcurrentModificationException.class) + public void concurrentModification() { + map.mark(nodes[7]); + + map.mark(nodes[99]); + map.mark(nodes[0]); + map.mark(nodes[7]); + map.mark(nodes[1]); + map.mark(nodes[53]); + + Iterator iter = map.iterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[0], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[1], iter.next()); + Assert.assertTrue(iter.hasNext()); + nodes[7].markDeleted(); + iter.next(); + } + + @Test + public void nextWithoutHasNext() { + map.mark(nodes[99]); + map.mark(nodes[0]); + map.mark(nodes[7]); + map.mark(nodes[1]); + map.mark(nodes[53]); + + Iterator iter = map.iterator(); + Assert.assertEquals(nodes[0], iter.next()); + Assert.assertEquals(nodes[1], iter.next()); + Assert.assertEquals(nodes[7], iter.next()); + Assert.assertEquals(nodes[53], iter.next()); + Assert.assertEquals(nodes[99], iter.next()); + Assert.assertFalse(iter.hasNext()); + } + + @Test + public void markWhileIterating() { + map.mark(nodes[0]); + + Iterator iter = map.iterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[0], iter.next()); + map.mark(nodes[7]); + Assert.assertTrue(iter.hasNext()); + map.mark(nodes[1]); + Assert.assertEquals(nodes[7], iter.next()); + map.mark(nodes[99]); + map.mark(nodes[53]); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[53], iter.next()); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals(nodes[99], iter.next()); + Assert.assertFalse(iter.hasNext()); + } +} diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeBitMap.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeBitMap.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeBitMap.java Mon Aug 28 22:45:56 2017 +0000 @@ -23,22 +23,23 @@ package org.graalvm.compiler.graph; import java.util.Arrays; +import java.util.ConcurrentModificationException; import java.util.Iterator; +import java.util.NoSuchElementException; import org.graalvm.compiler.graph.iterators.NodeIterable; -public final class NodeBitMap implements NodeIterable { +public final class NodeBitMap extends NodeIdAccessor implements NodeIterable { private static final int SHIFT = 6; private long[] bits; private int nodeCount; private int counter; - private final Graph graph; public NodeBitMap(Graph graph) { + super(graph); this.nodeCount = graph.nodeIdCount(); this.bits = new long[sizeForNodeCount(nodeCount)]; - this.graph = graph; } private static int sizeForNodeCount(int nodeCount) { @@ -50,9 +51,9 @@ } private NodeBitMap(NodeBitMap other) { + super(other.graph); this.bits = other.bits.clone(); this.nodeCount = other.nodeCount; - this.graph = other.graph; } public Graph graph() { @@ -60,12 +61,12 @@ } public boolean isNew(Node node) { - return node.id() >= nodeCount; + return getNodeId(node) >= nodeCount; } public boolean isMarked(Node node) { assert check(node, false); - return isMarked(node.id()); + return isMarked(getNodeId(node)); } public boolean checkAndMarkInc(Node node) { @@ -84,33 +85,33 @@ public boolean isMarkedAndGrow(Node node) { assert check(node, true); - int id = node.id(); + int id = getNodeId(node); checkGrow(id); return isMarked(id); } public void mark(Node node) { assert check(node, false); - int id = node.id(); + int id = getNodeId(node); bits[id >> SHIFT] |= (1L << id); } public void markAndGrow(Node node) { assert check(node, true); - int id = node.id(); + int id = getNodeId(node); checkGrow(id); bits[id >> SHIFT] |= (1L << id); } public void clear(Node node) { assert check(node, false); - int id = node.id(); + int id = getNodeId(node); bits[id >> SHIFT] &= ~(1L << id); } public void clearAndGrow(Node node) { assert check(node, true); - int id = node.id(); + int id = getNodeId(node); checkGrow(id); bits[id >> SHIFT] &= ~(1L << id); } @@ -181,15 +182,30 @@ } } - protected int nextMarkedNodeId(int fromNodeId) { + protected Node nextMarkedNode(int fromNodeId) { assert fromNodeId >= 0; int wordIndex = fromNodeId >> SHIFT; int wordsInUse = bits.length; if (wordIndex < wordsInUse) { - long word = bits[wordIndex] & (0xFFFFFFFFFFFFFFFFL << fromNodeId); + long word = getPartOfWord(bits[wordIndex], fromNodeId); while (true) { - if (word != 0) { - return wordIndex * Long.SIZE + Long.numberOfTrailingZeros(word); + while (word != 0) { + int bitIndex = Long.numberOfTrailingZeros(word); + int nodeId = wordIndex * Long.SIZE + bitIndex; + Node result = graph.getNode(nodeId); + if (result == null) { + // node was deleted -> clear the bit and continue searching + bits[wordIndex] = bits[wordIndex] & ~(1 << bitIndex); + int nextNodeId = nodeId + 1; + if ((nextNodeId & (Long.SIZE - 1)) == 0) { + // we reached the end of this word + break; + } else { + word = getPartOfWord(word, nextNodeId); + } + } else { + return result; + } } if (++wordIndex == wordsInUse) { break; @@ -197,30 +213,56 @@ word = bits[wordIndex]; } } - return -2; + return null; + } + + private static long getPartOfWord(long word, int firstNodeIdToInclude) { + return word & (0xFFFFFFFFFFFFFFFFL << firstNodeIdToInclude); } + /** + * This iterator only returns nodes that are marked in the {@link NodeBitMap} and are alive in + * the corresponding {@link Graph}. + */ private class MarkedNodeIterator implements Iterator { - private int nextNodeId; + private int currentNodeId; + private Node currentNode; MarkedNodeIterator() { - nextNodeId = -1; + currentNodeId = -1; forward(); } private void forward() { - nextNodeId = NodeBitMap.this.nextMarkedNodeId(nextNodeId + 1); + assert currentNode == null; + currentNode = NodeBitMap.this.nextMarkedNode(currentNodeId + 1); + if (currentNode != null) { + assert currentNode.isAlive(); + currentNodeId = getNodeId(currentNode); + } else { + currentNodeId = -1; + } } @Override public boolean hasNext() { - return nextNodeId >= 0; + if (currentNode == null && currentNodeId >= 0) { + forward(); + } + return currentNodeId >= 0; } @Override public Node next() { - Node result = graph.getNode(nextNodeId); - forward(); + if (!hasNext()) { + throw new NoSuchElementException(); + } + if (!currentNode.isAlive()) { + throw new ConcurrentModificationException("NodeBitMap was modified between the calls to hasNext() and next()"); + } + + Node result = currentNode; + currentNode = null; return result; } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64RawNativeCallNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64RawNativeCallNode.java Mon Aug 28 21:46:13 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.aarch64; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; - -import org.graalvm.compiler.core.aarch64.AArch64NodeLIRBuilder; -import org.graalvm.compiler.core.common.type.RawPointerStamp; -import org.graalvm.compiler.core.common.type.Stamp; -import org.graalvm.compiler.core.common.type.StampFactory; -import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.graph.NodeInputList; -import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodes.FixedWithNextNode; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.spi.LIRLowerable; -import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; - -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.hotspot.HotSpotCallingConventionType; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Value; - -@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = SIZE_UNKNOWN) -public final class AArch64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass TYPE = NodeClass.create(AArch64RawNativeCallNode.class); - - protected final JavaConstant functionPointer; - @Input NodeInputList args; - - public AArch64RawNativeCallNode(JavaKind returnType, JavaConstant functionPointer, ValueNode[] args) { - super(TYPE, StampFactory.forKind(returnType)); - this.functionPointer = functionPointer; - this.args = new NodeInputList<>(this, args); - } - - private static class PointerType implements JavaType { - - @Override - public String getName() { - return "void*"; - } - - @Override - public JavaType getComponentType() { - return null; - } - - @Override - public JavaType getArrayClass() { - return null; - } - - @Override - public JavaKind getJavaKind() { - // native pointers and java objects use the same registers in the calling convention - return JavaKind.Object; - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - return null; - } - } - - private static JavaType toJavaType(Stamp stamp, MetaAccessProvider metaAccess) { - if (stamp instanceof RawPointerStamp) { - return new PointerType(); - } else { - return stamp.javaType(metaAccess); - } - } - - @Override - public void generate(NodeLIRBuilderTool generator) { - AArch64NodeLIRBuilder gen = (AArch64NodeLIRBuilder) generator; - Value[] parameter = new Value[args.count()]; - JavaType[] parameterTypes = new JavaType[args.count()]; - for (int i = 0; i < args.count(); i++) { - parameter[i] = generator.operand(args.get(i)); - parameterTypes[i] = toJavaType(args.get(i).stamp(), gen.getLIRGeneratorTool().getMetaAccess()); - } - JavaType returnType = toJavaType(stamp(), gen.getLIRGeneratorTool().getMetaAccess()); - CallingConvention cc = generator.getLIRGeneratorTool().getCodeCache().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.NativeCall, returnType, parameterTypes, - generator.getLIRGeneratorTool()); - gen.getLIRGeneratorTool().emitCCall(functionPointer.asLong(), cc, parameter); - if (this.getStackKind() != JavaKind.Void) { - generator.setResult(this, gen.getLIRGeneratorTool().emitMove(cc.getReturn())); - } - } - -} diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64RawNativeCallNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64RawNativeCallNode.java Mon Aug 28 21:46:13 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.amd64; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; - -import org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder; -import org.graalvm.compiler.core.common.type.RawPointerStamp; -import org.graalvm.compiler.core.common.type.Stamp; -import org.graalvm.compiler.core.common.type.StampFactory; -import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.graph.NodeInputList; -import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodeinfo.NodeSize; -import org.graalvm.compiler.nodes.FixedWithNextNode; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.spi.LIRLowerable; -import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; - -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.hotspot.HotSpotCallingConventionType; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Value; - -@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = NodeSize.SIZE_UNKNOWN) -public final class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass TYPE = NodeClass.create(AMD64RawNativeCallNode.class); - - protected final JavaConstant functionPointer; - @Input NodeInputList args; - - public AMD64RawNativeCallNode(JavaKind returnType, JavaConstant functionPointer, ValueNode[] args) { - super(TYPE, StampFactory.forKind(returnType)); - this.functionPointer = functionPointer; - this.args = new NodeInputList<>(this, args); - } - - private static class PointerType implements JavaType { - - @Override - public String getName() { - return "void*"; - } - - @Override - public JavaType getComponentType() { - return null; - } - - @Override - public JavaType getArrayClass() { - return null; - } - - @Override - public JavaKind getJavaKind() { - // native pointers and java objects use the same registers in the calling convention - return JavaKind.Object; - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - return null; - } - } - - private static JavaType toJavaType(Stamp stamp, MetaAccessProvider metaAccess) { - if (stamp instanceof RawPointerStamp) { - return new PointerType(); - } else { - return stamp.javaType(metaAccess); - } - } - - @Override - public void generate(NodeLIRBuilderTool generator) { - AMD64NodeLIRBuilder gen = (AMD64NodeLIRBuilder) generator; - Value[] parameter = new Value[args.count()]; - JavaType[] parameterTypes = new JavaType[args.count()]; - for (int i = 0; i < args.count(); i++) { - parameter[i] = generator.operand(args.get(i)); - parameterTypes[i] = toJavaType(args.get(i).stamp(), gen.getLIRGeneratorTool().getMetaAccess()); - } - JavaType returnType = toJavaType(stamp(), gen.getLIRGeneratorTool().getMetaAccess()); - CallingConvention cc = generator.getLIRGeneratorTool().getCodeCache().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.NativeCall, returnType, parameterTypes, - generator.getLIRGeneratorTool()); - gen.getLIRGeneratorTool().emitCCall(functionPointer.asLong(), cc, parameter, countFloatingTypeArguments(args)); - if (this.getStackKind() != JavaKind.Void) { - generator.setResult(this, gen.getLIRGeneratorTool().emitMove(cc.getReturn())); - } - } - - private static int countFloatingTypeArguments(NodeInputList args) { - int count = 0; - for (ValueNode n : args) { - if (n.getStackKind() == JavaKind.Double || n.getStackKind() == JavaKind.Float) { - count++; - } - } - if (count > 8) { - return 8; - } - return count; - } - -} diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Mon Aug 28 22:45:56 2017 +0000 @@ -207,7 +207,6 @@ "oracle/jrockit/jfr/Timing.counterTime()J", "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J", "oracle/jrockit/jfr/VMJFR.threadID()I", - "sun/misc/Unsafe.copyMemory(Ljava/lang/Object;JLjava/lang/Object;JJ)V", "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I", "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I", "sun/security/provider/SHA.implCompress([BI)V", @@ -273,7 +272,6 @@ "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S", "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z", "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z", - "jdk/internal/misc/Unsafe.copyMemory0(Ljava/lang/Object;JLjava/lang/Object;JJ)V", "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B", "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S", "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B", diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java Mon Aug 28 22:45:56 2017 +0000 @@ -0,0 +1,81 @@ +/* + * 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 org.graalvm.compiler.replacements.test.MethodSubstitutionTest; +import org.junit.Test; + +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import sun.misc.Unsafe; + +/** + * Tests the VM independent intrinsification of {@link Unsafe} methods. + */ +public class HotSpotUnsafeSubstitutionTest extends MethodSubstitutionTest { + + public void testSubstitution(String testMethodName, Class holder, String methodName, Class[] parameterTypes, Object receiver, Object[] args1, Object[] args2) { + ResolvedJavaMethod testMethod = getResolvedJavaMethod(testMethodName); + ResolvedJavaMethod originalMethod = getResolvedJavaMethod(holder, methodName, parameterTypes); + + // Force compilation + InstalledCode code = getCode(testMethod); + assert code != null; + + // Verify that the original method and the substitution produce the same value + Object expected = invokeSafe(originalMethod, receiver, args1); + Object actual = invokeSafe(testMethod, null, args2); + assertDeepEquals(expected, actual); + + // Verify that the generated code and the original produce the same value + expected = invokeSafe(originalMethod, receiver, args1); + actual = executeVarargsSafe(code, args2); + assertDeepEquals(expected, actual); + + } + + @Test + public void testUnsafeSubstitutions() throws Exception { + testGraph("unsafeCopyMemory"); + } + + public void unsafeCopyMemory(Object srcBase, long srcOffset, Object dstBase, long dstOffset, long bytes) { + UNSAFE.copyMemory(srcBase, srcOffset, dstBase, dstOffset, bytes); + } + + public byte[] testCopyMemorySnippet(long src, int bytes) { + byte[] result = new byte[bytes]; + UNSAFE.copyMemory(null, src, result, Unsafe.ARRAY_BYTE_BASE_OFFSET, bytes); + return result; + } + + @Test + public void testCopyMemory() { + int size = 128; + long src = UNSAFE.allocateMemory(size); + for (int i = 0; i < size; i++) { + UNSAFE.putByte(null, src + i, (byte) i); + } + test("testCopyMemorySnippet", src, size); + } +} diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Mon Aug 28 22:45:56 2017 +0000 @@ -64,9 +64,9 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.tiers.SuitesProvider; import org.graalvm.compiler.word.Word; -import org.graalvm.util.Equivalence; import org.graalvm.util.EconomicMap; import org.graalvm.util.EconomicSet; +import org.graalvm.util.Equivalence; import org.graalvm.util.MapCursor; import org.graalvm.word.Pointer; @@ -258,6 +258,18 @@ private static native void sha5ImplCompressStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state); /** + * @see org.graalvm.compiler.hotspot.meta.HotSpotUnsafeSubstitutions#copyMemory + */ + public static final ForeignCallDescriptor UNSAFE_ARRAYCOPY = new ForeignCallDescriptor("unsafe_arraycopy", void.class, Word.class, Word.class, Word.class); + + public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) { + unsafeArraycopyStub(HotSpotBackend.UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size); + } + + @NodeIntrinsic(ForeignCallNode.class) + private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size); + + /** * @see VMErrorNode */ public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, Object.class, Object.class, long.class); diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Mon Aug 28 22:45:56 2017 +0000 @@ -198,7 +198,7 @@ public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) { StructuredGraph graph = createGraph(method, entryBCI, useProfilingInfo, compilationId, options, debug); - CompilationResult result = new CompilationResult(); + CompilationResult result = new CompilationResult(compilationId); return compileHelper(CompilationResultBuilderFactory.Default, result, graph, method, entryBCI, useProfilingInfo, options); } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Aug 28 22:45:56 2017 +0000 @@ -111,6 +111,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; +import sun.misc.Unsafe; /** * Defines the {@link Plugins} used when running on HotSpot. @@ -202,6 +203,7 @@ registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider); registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider); registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider); + registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider); StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true); for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) { @@ -313,6 +315,17 @@ r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class); } + private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementBytecodeProvider) { + Registration r; + if (Java8OrEarlier) { + r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider); + } else { + r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider); + } + r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, "copyMemory", Receiver.class, Object.class, long.class, Object.class, long.class, + long.class); + } + private static final LocationIdentity INSTANCE_KLASS_CONSTANTS = NamedLocationIdentity.immutable("InstanceKlass::_constants"); private static final LocationIdentity CONSTANT_POOL_LENGTH = NamedLocationIdentity.immutable("ConstantPool::_length"); diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Mon Aug 28 22:45:56 2017 +0000 @@ -51,6 +51,7 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA5_IMPL_COMPRESS; import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS; import static org.graalvm.compiler.hotspot.HotSpotBackend.SQUARE_TO_LEN; +import static org.graalvm.compiler.hotspot.HotSpotBackend.UNSAFE_ARRAYCOPY; import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER; import static org.graalvm.compiler.hotspot.HotSpotBackend.VM_ERROR; import static org.graalvm.compiler.hotspot.HotSpotBackend.WRONG_METHOD_HANDLER; @@ -330,6 +331,8 @@ registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit); registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy); + registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); + if (c.useMultiplyToLenIntrinsic()) { registerForeignCall(MULTIPLY_TO_LEN, c.multiplyToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java Mon Aug 28 22:45:56 2017 +0000 @@ -0,0 +1,47 @@ +/* + * 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.meta; + +import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; + +import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.MethodSubstitution; +import org.graalvm.compiler.hotspot.HotSpotBackend; +import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode; +import org.graalvm.compiler.word.Word; +import org.graalvm.word.WordFactory; + +@ClassSubstitution(className = {"jdk.internal.misc.Unsafe", "sun.misc.Unsafe"}) +public class HotSpotUnsafeSubstitutions { + + public static final String copyMemoryName = Java8OrEarlier ? "copyMemory" : "copyMemory0"; + + @SuppressWarnings("unused") + @MethodSubstitution(isStatic = false) + static void copyMemory(Object receiver, Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) { + Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset)); + Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset)); + Word size = Word.signed(bytes); + HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size); + } +} diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java Mon Aug 28 22:45:56 2017 +0000 @@ -216,8 +216,9 @@ @SuppressWarnings("try") private CompilationResult buildCompilationResult(DebugContext debug, final Backend backend) { - CompilationResult compResult = new CompilationResult(toString(), GeneratePIC.getValue(options)); - final StructuredGraph graph = getGraph(debug, getStubCompilationId()); + CompilationIdentifier compilationId = getStubCompilationId(); + final StructuredGraph graph = getGraph(debug, compilationId); + CompilationResult compResult = new CompilationResult(compilationId, toString(), GeneratePIC.getValue(options)); // Stubs cannot be recompiled so they cannot be compiled with assumptions assert graph.getAssumptions() == null; diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java Mon Aug 28 22:45:56 2017 +0000 @@ -365,10 +365,6 @@ return intTo; } - int numUsePositions() { - return numUsePos(); - } - public void setLocationHint(IntervalHint interval) { locationHint = interval; } @@ -452,6 +448,10 @@ return spillSt == SpillState.StartInMemory || (spillSt == SpillState.SpillStore && opId > spillDefinitionPos() && !canMaterialize()); } + public boolean preSpilledAllocated() { + return spillState() == SpillState.StartInMemory && numUsePos() == 0 && !hasHint(); + } + // test intersection boolean intersects(TraceInterval i) { return intersectsAt(i) != -1; diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java Mon Aug 28 22:45:56 2017 +0000 @@ -541,16 +541,23 @@ assert instructionIndex == 0 : "not at start?" + instructionIndex; handleTraceBegin(blocks[0]); - // fix spill state for phi/incoming intervals - for (TraceInterval interval : allocator.intervals()) { - if (interval != null && interval.spillState().equals(SpillState.NoDefinitionFound) && interval.spillDefinitionPos() != -1) { - // there was a definition in a phi/incoming - interval.setSpillState(SpillState.NoSpillStore); - } - } if (TraceRAuseInterTraceHints.getValue(allocator.getLIR().getOptions())) { addInterTraceHints(); } + // fix spill state for phi/incoming intervals + for (TraceInterval interval : allocator.intervals()) { + if (interval != null) { + if (interval.spillState().equals(SpillState.NoDefinitionFound) && interval.spillDefinitionPos() != -1) { + // there was a definition in a phi/incoming + interval.setSpillState(SpillState.NoSpillStore); + } + if (interval.preSpilledAllocated()) { + // pre-spill unused, start in memory intervals + allocator.assignSpillSlot(interval); + } + } + } + for (FixedInterval interval1 : allocator.fixedIntervals()) { if (interval1 != null) { /* We use [-1, 0] to avoid intersection with incoming values. */ diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java Mon Aug 28 22:45:56 2017 +0000 @@ -153,7 +153,7 @@ @Override public boolean apply(TraceInterval i) { // all TraceIntervals are variable intervals - return true; + return !i.preSpilledAllocated(); } }; private static final Comparator SORT_BY_FROM_COMP = new Comparator() { diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/lir/GraalCompilerState.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/lir/GraalCompilerState.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/lir/GraalCompilerState.java Mon Aug 28 22:45:56 2017 +0000 @@ -319,7 +319,7 @@ assert !graph.isFrozen(); ResolvedJavaMethod installedCodeOwner = graph.method(); request = new Request<>(graph, installedCodeOwner, getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, - graph.getProfilingInfo(), createSuites(getOptions()), createLIRSuites(getOptions()), new CompilationResult(), CompilationResultBuilderFactory.Default); + graph.getProfilingInfo(), createSuites(getOptions()), createLIRSuites(getOptions()), new CompilationResult(graph.compilationId()), CompilationResultBuilderFactory.Default); } /** diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java Mon Aug 28 22:45:56 2017 +0000 @@ -209,7 +209,6 @@ int nodeCount = nodeOrder.nextOrderId; assert nodeOrder.orderIds.get(graph.start()) == START_NODE_ORDER_ID; assert nodeOrder.orderIds.get(graph.start().next()) == FIRST_NODE_ORDER_ID; - assert nodeCount == graph.getNodeCount() + 1; long[] nodeStartOffsets = new long[nodeCount]; UnmodifiableMapCursor cursor = nodeOrder.orderIds.getEntries(); @@ -218,6 +217,7 @@ Integer orderId = cursor.getValue(); assert !(node instanceof AbstractBeginNode) || nodeOrder.orderIds.get(((AbstractBeginNode) node).next()) == orderId + BEGIN_NEXT_ORDER_ID_OFFSET; + assert nodeStartOffsets[orderId] == 0; nodeStartOffsets[orderId] = writer.getBytesWritten(); /* Write out the type, properties, and edges. */ @@ -284,7 +284,6 @@ writer.putUV(nodeOrder.maxFixedNodeOrderId); writer.putUV(nodeCount); for (int i = 0; i < nodeCount; i++) { - assert i == NULL_ORDER_ID || i == START_NODE_ORDER_ID || nodeStartOffsets[i] > 0; writer.putUV(metadataStart - nodeStartOffsets[i]); } @@ -344,8 +343,25 @@ } while (current != null); maxFixedNodeOrderId = nextOrderId - 1; + + /* + * Emit all parameters consecutively at a known location (after all fixed nodes). This + * allows substituting parameters when inlining during decoding by pre-initializing the + * decoded node list. + * + * Note that not all parameters must be present (unused parameters are deleted after + * parsing). This leads to holes in the orderId, i.e., unused orderIds. + */ + int parameterCount = graph.method().getSignature().getParameterCount(!graph.method().isStatic()); + for (ParameterNode node : graph.getNodes(ParameterNode.TYPE)) { + assert orderIds.get(node) == null : "Parameter node must not be ordered yet"; + assert node.index() < parameterCount : "Parameter index out of range"; + orderIds.set(node, nextOrderId + node.index()); + } + nextOrderId += parameterCount; + for (Node node : graph.getNodes()) { - assert (node instanceof FixedNode) == (orderIds.get(node) != null) : "all fixed nodes must be ordered: " + node; + assert (node instanceof FixedNode || node instanceof ParameterNode) == (orderIds.get(node) != null) : "all fixed nodes and ParameterNodes must be ordered: " + node; add(node); } } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Mon Aug 28 22:45:56 2017 +0000 @@ -37,6 +37,7 @@ import org.graalvm.compiler.bytecode.BytecodeDisassembler; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.DisassemblerProvider; +import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.alloc.Trace; import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; @@ -72,6 +73,7 @@ private CFGPrinter cfgPrinter; private File cfgFile; private JavaMethod curMethod; + private CompilationIdentifier curCompilation; private List curDecorators = Collections.emptyList(); @Override @@ -92,6 +94,7 @@ */ private boolean checkMethodScope(DebugContext debug) { JavaMethod method = null; + CompilationIdentifier compilation = null; ArrayList decorators = new ArrayList<>(); for (Object o : debug.context()) { if (o instanceof JavaMethod) { @@ -102,22 +105,33 @@ if (graph.method() != null) { method = graph.method(); decorators.clear(); + compilation = graph.compilationId(); } } else if (o instanceof DebugDumpScope) { DebugDumpScope debugDumpScope = (DebugDumpScope) o; if (debugDumpScope.decorator) { decorators.add(debugDumpScope.name); } + } else if (o instanceof CompilationResult) { + CompilationResult compilationResult = (CompilationResult) o; + compilation = compilationResult.getCompilationId(); } } - if (method == null) { + if (method == null && compilation == null) { return false; } - if (!method.equals(curMethod) || !curDecorators.equals(decorators)) { - cfgPrinter.printCompilation(method); + if (compilation != null) { + if (!compilation.equals(curCompilation) || !curDecorators.equals(decorators)) { + cfgPrinter.printCompilation(compilation); + } + } else { + if (!method.equals(curMethod) || !curDecorators.equals(decorators)) { + cfgPrinter.printCompilation(method); + } } + curCompilation = compilation; curMethod = method; curDecorators = decorators; return true; @@ -277,6 +291,7 @@ cfgPrinter = null; curDecorators = Collections.emptyList(); curMethod = null; + curCompilation = null; } } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CompilationPrinter.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CompilationPrinter.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CompilationPrinter.java Mon Aug 28 22:45:56 2017 +0000 @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; +import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.debug.LogStream; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.lir.util.IndexedValueMap; @@ -115,12 +116,25 @@ /** * Prints a compilation timestamp for a given method. * - * @param method the method for which a timestamp will be printed + * @param javaMethod the method for which a timestamp will be printed */ - public void printCompilation(JavaMethod method) { + public void printCompilation(JavaMethod javaMethod) { + printCompilation(javaMethod.format("%H::%n"), javaMethod.format("%f %r %H.%n(%p)")); + } + + /** + * Prints a compilation id. + * + * @param compilationId the compilation method for which an id will be printed + */ + public void printCompilation(CompilationIdentifier compilationId) { + printCompilation(compilationId.toString(CompilationIdentifier.Verbosity.DETAILED), compilationId.toString(CompilationIdentifier.Verbosity.DETAILED)); + } + + private void printCompilation(final String name, String method) { begin("compilation"); - out.print("name \" ").print(method.format("%H::%n")).println('"'); - out.print("method \"").print(method.format("%f %r %H.%n(%p)")).println('"'); + out.print("name \" ").print(name).println('"'); + out.print("method \"").print(method).println('"'); out.print("date ").println(System.currentTimeMillis()); end("compilation"); } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.verifier/src/org/graalvm/compiler/replacements/verifier/ClassSubstitutionVerifier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.verifier/src/org/graalvm/compiler/replacements/verifier/ClassSubstitutionVerifier.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.verifier/src/org/graalvm/compiler/replacements/verifier/ClassSubstitutionVerifier.java Mon Aug 28 22:45:56 2017 +0000 @@ -95,10 +95,13 @@ TypeElement typeElement = null; for (String className : classNames) { typeElement = env.getElementUtils().getTypeElement(className); - if (typeElement == null && !optional) { - env.getMessager().printMessage(Kind.ERROR, String.format("The class '%s' was not found on the classpath.", stringValue), sourceElement, classSubstition, stringValue); + if (typeElement != null) { + break; } } + if (typeElement == null && !optional) { + env.getMessager().printMessage(Kind.ERROR, String.format("The class '%s' was not found on the classpath.", stringValue), sourceElement, classSubstition, stringValue); + } return typeElement; } diff -r 4a7708303807 -r eb6459334399 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Mon Aug 28 22:45:56 2017 +0000 @@ -707,10 +707,22 @@ } } + LoopScope inlineLoopScope = createInitialLoopScope(inlineScope, predecessor); + + /* + * The GraphEncoder assigns parameters a nodeId immediately after the fixed nodes. + * Initializing createdNodes here avoid decoding and immediately replacing the + * ParameterNodes. + */ + int firstArgumentNodeId = inlineScope.maxFixedNodeOrderId + 1; + for (int i = 0; i < arguments.length; i++) { + inlineLoopScope.createdNodes[firstArgumentNodeId + i] = arguments[i]; + } + /* * Do the actual inlining by returning the initial loop scope for the inlined method scope. */ - return createInitialLoopScope(inlineScope, predecessor); + return inlineLoopScope; } @Override @@ -1028,9 +1040,7 @@ if (node instanceof ParameterNode) { ParameterNode param = (ParameterNode) node; if (methodScope.isInlinedMethod()) { - Node result = methodScope.arguments[param.index()]; - assert result != null; - return result; + throw GraalError.shouldNotReachHere("Parameter nodes are already registered when the inlined scope is created"); } else if (parameterPlugin != null) { assert !methodScope.isInlinedMethod(); diff -r 4a7708303807 -r eb6459334399 hotspot/src/share/vm/aot/aotCodeHeap.cpp --- a/hotspot/src/share/vm/aot/aotCodeHeap.cpp Mon Aug 28 21:46:13 2017 +0200 +++ b/hotspot/src/share/vm/aot/aotCodeHeap.cpp Mon Aug 28 22:45:56 2017 +0000 @@ -478,6 +478,8 @@ SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_arrayof_oop_disjoint_arraycopy", address, StubRoutines::_arrayof_oop_disjoint_arraycopy); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_arrayof_oop_disjoint_arraycopy_uninit", address, StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit); + SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_unsafe_arraycopy", address, StubRoutines::_unsafe_arraycopy); + SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_checkcast_arraycopy", address, StubRoutines::_checkcast_arraycopy); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_encryptBlock", address, StubRoutines::_aescrypt_encryptBlock);