# HG changeset patch # User Thomas Wuerthinger # Date 1399941101 -7200 # Node ID 8df3b6d4a035974749a5a2a8c6363ad6ce1c0f32 # Parent 2d5f9c7379c1074f0cd6b9df7f201d0207d95f94# Parent d556971b409ca9f5ff13900d8b7b82549fd1f17a Merge. diff -r 2d5f9c7379c1 -r 8df3b6d4a035 CHANGELOG.md --- a/CHANGELOG.md Tue May 13 02:31:20 2014 +0200 +++ b/CHANGELOG.md Tue May 13 02:31:41 2014 +0200 @@ -2,9 +2,10 @@ ## `tip` ### Graal -* ... +* Made initialization of Graal runtime lazy in hosted mode. ### Truffle +* `truffle.jar`: strip out build-time only dependency into a seperated JAR file (`truffle-dsl-processor.jar`) * ... ## Version 0.3 @@ -74,4 +75,3 @@ * Initial version of a multi-language framework on top of Graal. * Update of the [Truffle Inlining API](http://mail.openjdk.java.net/pipermail/graal-dev/2014-January/001516.html). - diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue May 13 02:31:41 2014 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*; +import static sun.reflect.Reflection.*; import java.lang.reflect.*; import java.util.*; @@ -54,9 +55,26 @@ */ public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider, StackIntrospection { - private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime(); + private static final HotSpotGraalRuntime instance; + + /** + * Initializes the native part of the Graal runtime. + */ + private static native void init(Class compilerToVMClass); + static { + init(CompilerToVMImpl.class); + + // The options must be processed before any code using them... + HotSpotOptions.initialize(); + + // ... including code in the constructor + instance = new HotSpotGraalRuntime(); + + // Why deferred initialization? See comment in completeInitialization(). instance.completeInitialization(); + + registerFieldsToFilter(HotSpotGraalRuntime.class, "instance"); } /** @@ -75,10 +93,6 @@ return instance; } - static { - Reflection.registerFieldsToFilter(HotSpotGraalRuntime.class, "instance"); - } - /** * Do deferred initialization. */ @@ -104,6 +118,8 @@ this.vmToCompiler = toCompiler; this.compilerToVm = toVM; + + this.vmToCompiler.startRuntime(); } // Options must not be directly declared in HotSpotGraalRuntime - see VerifyOptionsPhase diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue May 13 02:31:41 2014 +0200 @@ -87,7 +87,7 @@ try { for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) { if (!line.startsWith("#")) { - if (!setOption(line)) { + if (!parseOption(line, null)) { throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions); } } @@ -98,14 +98,39 @@ } } + /** + * Gets the Graal specific options specified to HotSpot (e.g., on the command line). + * + * @param timeCompilations (out) true if the CITime or CITimeEach HotSpot VM options are set + */ + private static native String[] getVMOptions(boolean[] timeCompilations); + static { initializeOptions(); loadOptionOverrides(); + + boolean[] timeCompilations = {false}; + for (String option : getVMOptions(timeCompilations)) { + if (!parseOption(option, null)) { + throw new InternalError("Invalid Graal option \"-G:" + option + "\""); + } + } + + if (timeCompilations[0] || PrintCompRate.getValue() != 0) { + unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes"); + unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime"); + } + assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " + + "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName(); + if (areDebugScopePatternsEnabled()) { + System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); + } } - // Called from VM code - public static boolean setOption(String option) { - return parseOption(option, null); + /** + * Ensures {@link HotSpotOptions} is initialized. + */ + public static void initialize() { } interface OptionConsumer { @@ -238,24 +263,6 @@ } /** - * Called from VM code once all Graal command line options have been processed by - * {@link #setOption(String)}. - * - * @param timeCompilations true if the CITime or CITimeEach HotSpot VM options are set - */ - public static void finalizeOptions(boolean timeCompilations) { - if (timeCompilations || PrintCompRate.getValue() != 0) { - unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes"); - unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime"); - } - assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " + - "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName(); - if (areDebugScopePatternsEnabled()) { - System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); - } - } - - /** * Wraps some given text to one or more lines of a given maximum width. * * @param text text to wrap diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Tue May 13 02:31:41 2014 +0200 @@ -30,7 +30,7 @@ */ public interface VMToCompiler { - void startRuntime() throws Throwable; + void startRuntime(); void startCompiler(boolean bootstrapEnabled) throws Throwable; diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue May 13 02:31:41 2014 +0200 @@ -142,7 +142,7 @@ this.runtime = runtime; } - public void startRuntime() throws Throwable { + public void startRuntime() { if (LogFile.getValue() != null) { try { diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Tue May 13 02:31:41 2014 +0200 @@ -41,5 +41,5 @@ public abstract Set getLocations(); - public abstract void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode); + public abstract boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode); } diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue May 13 02:31:41 2014 +0200 @@ -92,12 +92,15 @@ } @Override - public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { + public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { + boolean replaced = false; for (Map.Entry entry : lastMemorySnapshot.entrySet()) { if (entry.getValue() == oldNode) { entry.setValue(newNode); + replaced = true; } } + return replaced; } } diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningIterator.java Tue May 13 02:31:41 2014 +0200 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common.inlining; + +import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.NodeBitMap; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.LinkedList; + +/** + * Given a graph, visit all fixed nodes in dominator-based order, collecting in the process the + * {@link Invoke} nodes with {@link MethodCallTargetNode}. Such list of callsites is returned by + * {@link #apply()} + */ +class InliningIterator { + + private final StartNode start; + private final Deque nodeQueue; + private final NodeBitMap queuedNodes; + + public InliningIterator(StructuredGraph graph) { + this.start = graph.start(); + this.nodeQueue = new ArrayDeque<>(); + this.queuedNodes = graph.createNodeBitMap(); + assert start.isAlive(); + } + + public LinkedList apply() { + LinkedList invokes = new LinkedList<>(); + FixedNode current; + forcedQueue(start); + + while ((current = nextQueuedNode()) != null) { + assert current.isAlive(); + + if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) { + if (current != start) { + invokes.addLast((Invoke) current); + } + queueSuccessors(current); + } else if (current instanceof LoopBeginNode) { + queueSuccessors(current); + } else if (current instanceof LoopEndNode) { + // nothing to do + } else if (current instanceof MergeNode) { + queueSuccessors(current); + } else if (current instanceof FixedWithNextNode) { + queueSuccessors(current); + } else if (current instanceof EndNode) { + queueMerge((EndNode) current); + } else if (current instanceof ControlSinkNode) { + // nothing to do + } else if (current instanceof ControlSplitNode) { + queueSuccessors(current); + } else { + assert false : current; + } + } + + return invokes; + } + + private void queueSuccessors(FixedNode x) { + for (Node node : x.successors()) { + queue(node); + } + } + + private void queue(Node node) { + if (node != null && !queuedNodes.isMarked(node)) { + forcedQueue(node); + } + } + + private void forcedQueue(Node node) { + queuedNodes.mark(node); + nodeQueue.addFirst((FixedNode) node); + } + + private FixedNode nextQueuedNode() { + if (nodeQueue.isEmpty()) { + return null; + } + + FixedNode result = nodeQueue.removeFirst(); + assert queuedNodes.isMarked(result); + return result; + } + + private void queueMerge(AbstractEndNode end) { + MergeNode merge = end.merge(); + if (!queuedNodes.isMarked(merge) && visitedAllEnds(merge)) { + queuedNodes.mark(merge); + nodeQueue.add(merge); + } + } + + private boolean visitedAllEnds(MergeNode merge) { + for (int i = 0; i < merge.forwardEndCount(); i++) { + if (!queuedNodes.isMarked(merge.forwardEndAt(i))) { + return false; + } + } + return true; + } +} diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Tue May 13 02:31:41 2014 +0200 @@ -477,106 +477,13 @@ } } - private static class InliningIterator { - - private final FixedNode start; - private final Deque nodeQueue; - private final NodeBitMap queuedNodes; - - public InliningIterator(FixedNode start, NodeBitMap visitedFixedNodes) { - this.start = start; - this.nodeQueue = new ArrayDeque<>(); - this.queuedNodes = visitedFixedNodes; - assert start.isAlive(); - } - - public LinkedList apply() { - LinkedList invokes = new LinkedList<>(); - FixedNode current; - forcedQueue(start); - - while ((current = nextQueuedNode()) != null) { - assert current.isAlive(); - - if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) { - if (current != start) { - invokes.addLast((Invoke) current); - } - queueSuccessors(current); - } else if (current instanceof LoopBeginNode) { - queueSuccessors(current); - } else if (current instanceof LoopEndNode) { - // nothing todo - } else if (current instanceof MergeNode) { - queueSuccessors(current); - } else if (current instanceof FixedWithNextNode) { - queueSuccessors(current); - } else if (current instanceof EndNode) { - queueMerge((EndNode) current); - } else if (current instanceof ControlSinkNode) { - // nothing todo - } else if (current instanceof ControlSplitNode) { - queueSuccessors(current); - } else { - assert false : current; - } - } - - return invokes; - } - - private void queueSuccessors(FixedNode x) { - for (Node node : x.successors()) { - queue(node); - } - } - - private void queue(Node node) { - if (node != null && !queuedNodes.isMarked(node)) { - forcedQueue(node); - } - } - - private void forcedQueue(Node node) { - queuedNodes.mark(node); - nodeQueue.addFirst((FixedNode) node); - } - - private FixedNode nextQueuedNode() { - if (nodeQueue.isEmpty()) { - return null; - } - - FixedNode result = nodeQueue.removeFirst(); - assert queuedNodes.isMarked(result); - return result; - } - - private void queueMerge(AbstractEndNode end) { - MergeNode merge = end.merge(); - if (!queuedNodes.isMarked(merge) && visitedAllEnds(merge)) { - queuedNodes.mark(merge); - nodeQueue.add(merge); - } - } - - private boolean visitedAllEnds(MergeNode merge) { - for (int i = 0; i < merge.forwardEndCount(); i++) { - if (!queuedNodes.isMarked(merge.forwardEndAt(i))) { - return false; - } - } - return true; - } - } - /** * Holds the data for building the callee graphs recursively: graphs and invocations (each * invocation can have multiple graphs). */ static class InliningData { - private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new LinkedList(), 1.0, 1.0); + private static final GraphInfo DummyGraphInfo = new GraphInfo(null, 1.0, 1.0); /** * Call hierarchy from outer most call (i.e., compilation unit) to inner most callee. @@ -601,10 +508,7 @@ public void pushGraph(StructuredGraph graph, double probability, double relevance) { assert !contains(graph); - NodeBitMap visitedFixedNodes = graph.createNodeBitMap(); - LinkedList invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply(); - assert invokes.size() == count(graph.getInvokes()); - graphQueue.push(new GraphInfo(graph, invokes, probability, relevance)); + graphQueue.push(new GraphInfo(graph, probability, relevance)); assert graphQueue.size() <= maxGraphs; } @@ -712,16 +616,6 @@ } return false; } - - private static int count(Iterable invokes) { - int count = 0; - Iterator iterator = invokes.iterator(); - while (iterator.hasNext()) { - iterator.next(); - count++; - } - return count; - } } private static class MethodInvocation { @@ -803,13 +697,19 @@ private final ToDoubleFunction probabilities; private final ComputeInliningRelevance computeInliningRelevance; - public GraphInfo(StructuredGraph graph, LinkedList invokes, double probability, double relevance) { + public GraphInfo(StructuredGraph graph, double probability, double relevance) { this.graph = graph; - this.remainingInvokes = invokes; + if (graph == null) { + this.remainingInvokes = new LinkedList<>(); + } else { + LinkedList invokes = new InliningIterator(graph).apply(); + assert invokes.size() == count(graph.getInvokes()); + this.remainingInvokes = invokes; + } this.probability = probability; this.relevance = relevance; - if (graph != null && (graph.hasNode(InvokeNode.class) || graph.hasNode(InvokeWithExceptionNode.class))) { + if (graph != null && !remainingInvokes.isEmpty()) { probabilities = new FixedNodeProbabilityCache(); computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities); computeProbabilities(); @@ -819,6 +719,16 @@ } } + private static int count(Iterable invokes) { + int count = 0; + Iterator iterator = invokes.iterator(); + while (iterator.hasNext()) { + iterator.next(); + count++; + } + return count; + } + /** * Gets the method associated with the {@linkplain #graph() graph} represented by this * object. diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue May 13 02:31:41 2014 +0200 @@ -83,32 +83,56 @@ } private class KillSet implements Iterable { - private final Set set; + private List list; public KillSet() { - this.set = new ArraySet<>(); + list = null; } public KillSet(KillSet other) { - this.set = new HashSet<>(other.set); + if (other.list != null && other.list.size() > 0) { + list = new ArrayList<>(other.list); + } + } + + private void initSet() { + if (list == null) { + list = new ArrayList<>(4); + } } public void add(LocationIdentity locationIdentity) { - set.add(locationIdentity); + if (list == null || !list.contains(locationIdentity)) { + initSet(); + list.add(locationIdentity); + } } public void addAll(KillSet other) { - set.addAll(other.set); + if (other.list == null) { + return; + } + initSet(); + for (LocationIdentity locationIdentity : other) { + if (!list.contains(locationIdentity)) { + list.add(locationIdentity); + } + } } public Iterator iterator() { - return set.iterator(); + if (list == null) { + return Collections.emptyIterator(); + } + return list.iterator(); } public boolean isKilled(LocationIdentity locationIdentity) { - return set.contains(locationIdentity); + if (list == null) { + return false; + } + return list.contains(locationIdentity); } - } private class NewMemoryScheduleClosure extends BlockIteratorClosure { diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/ArraySet.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/ArraySet.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/ArraySet.java Tue May 13 02:31:41 2014 +0200 @@ -47,7 +47,7 @@ public boolean add(E e) { // avoid duplicated entries if (contains(e)) { - return true; + return false; } return super.add(e); } diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue May 13 02:31:41 2014 +0200 @@ -643,11 +643,6 @@ MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); - if (memoryAnchor.usages().isEmpty()) { - memoryAnchor.safeDelete(); - } else { - snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor); - } this.snippet = snippetCopy; @@ -656,9 +651,10 @@ List returnNodes = new ArrayList<>(4); List memMaps = new ArrayList<>(4); StartNode entryPointNode = snippet.start(); + boolean anchorUsed = false; for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) { MemoryMapNode memMap = retNode.getMemoryMap(); - memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor); + anchorUsed |= memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor); memMaps.add(memMap); retNode.setMemoryMap(null); returnNodes.add(retNode); @@ -666,6 +662,11 @@ memMap.safeDelete(); } } + if (memoryAnchor.usages().isEmpty() && !anchorUsed) { + memoryAnchor.safeDelete(); + } else { + snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor); + } assert snippet.getNodes().filter(MemoryMapNode.class).isEmpty(); if (returnNodes.isEmpty()) { this.returnNode = null; @@ -1009,7 +1010,7 @@ } @Override - public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { + public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { throw GraalInternalError.shouldNotReachHere(); } } diff -r 2d5f9c7379c1 -r 8df3b6d4a035 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Tue May 13 02:31:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Tue May 13 02:31:41 2014 +0200 @@ -33,7 +33,14 @@ private static final TruffleRuntime RUNTIME; - private static native TruffleRuntime initializeRuntime(); + /** + * Creates a new {@link TruffleRuntime} instance if the runtime has a specialized + * implementation. + * + * @throws UnsatisfiedLinkError if the runtime does not have a specialized implementation of + * {@link TruffleRuntime} + */ + private static native TruffleRuntime createRuntime(); public static TruffleRuntime getRuntime() { return RUNTIME; @@ -42,7 +49,7 @@ static { TruffleRuntime runtime; try { - runtime = initializeRuntime(); + runtime = createRuntime(); } catch (UnsatisfiedLinkError e) { runtime = new DefaultTruffleRuntime(); } diff -r 2d5f9c7379c1 -r 8df3b6d4a035 mx/projects --- a/mx/projects Tue May 13 02:31:20 2014 +0200 +++ b/mx/projects Tue May 13 02:31:41 2014 +0200 @@ -87,7 +87,7 @@ distribution@TRUFFLE-DSL-PROCESSOR@sourcesPath=truffle-dsl-processor-sources.jar distribution@TRUFFLE-DSL-PROCESSOR@dependencies=\ com.oracle.truffle.dsl.processor -distribution@TRUFFLE-DSL-PROCESSOR@exclude=com.oracle.truffle.api.dsl,com.oracle.truffle.api +distribution@TRUFFLE-DSL-PROCESSOR@distDependency=TRUFFLE # graal.api.collections project@com.oracle.graal.api.collections@subDir=graal diff -r 2d5f9c7379c1 -r 8df3b6d4a035 mxtool/mx.py --- a/mxtool/mx.py Tue May 13 02:31:20 2014 +0200 +++ b/mxtool/mx.py Tue May 13 02:31:41 2014 +0200 @@ -62,7 +62,7 @@ A distribution is a jar or zip file containing the output from one or more Java projects. """ class Distribution: - def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies): + def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies, distDependency): self.suite = suite self.name = name self.path = path.replace('/', os.sep) @@ -71,6 +71,7 @@ self.deps = deps self.update_listeners = set() self.excludedDependencies = excludedDependencies + self.distDependency = distDependency def sorted_deps(self, includeLibs=False): try: @@ -124,6 +125,11 @@ srcArc.zf.writestr(arcname, lp.read(arcname)) else: p = dep + + if self.distDependency and p in _dists[self.distDependency].sorted_deps(): + logv("Excluding {0} from {1} because it's provided by the dependency {2}".format(p.name, self.path, self.distDependency)) + continue + # skip a Java project if its Java compliance level is "higher" than the configured JDK jdk = java(p.javaCompliance) if not jdk: @@ -749,7 +755,8 @@ sourcesPath = attrs.pop('sourcesPath', None) deps = pop_list(attrs, 'dependencies') exclDeps = pop_list(attrs, 'exclude') - d = Distribution(self, name, path, sourcesPath, deps, exclDeps) + distDep = attrs.pop('distDependency', None) + d = Distribution(self, name, path, sourcesPath, deps, exclDeps, distDep) d.__dict__.update(attrs) self.dists.append(d) diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue May 13 02:31:41 2014 +0200 @@ -297,8 +297,6 @@ template(com_oracle_graal_graph_NodeClass, "com/oracle/graal/graph/NodeClass") \ /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ - template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ - template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode, "com/oracle/graal/hotspot/HotSpotCompiledCode") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment") \ template(com_oracle_graal_hotspot_HotSpotCompiledNmethod, "com/oracle/graal/hotspot/HotSpotCompiledNmethod") \ diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Tue May 13 02:31:41 2014 +0200 @@ -48,8 +48,6 @@ return; } - GraalRuntime::initialize(); - BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob(); if (!UseGraalCompilationQueue) { // This path is used for initialization both by the native queue and the graal queue @@ -68,7 +66,11 @@ bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal); VMToCompiler::startCompiler(bootstrap); _started = true; + + // Graal is considered as application code so we need to + // stop the VM deferring compilation now. CompilationPolicy::completed_vm_startup(); + if (bootstrap) { // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping. FlagSetting a(UseInterpreter, true); diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Tue May 13 02:31:41 2014 +0200 @@ -37,97 +37,30 @@ #include "utilities/debug.hpp" address GraalRuntime::_external_deopt_i2c_entry = NULL; -volatile GraalRuntime::State GraalRuntime::_state = uninitialized; -Thread* GraalRuntime::_initializingThread = NULL; -bool GraalRuntime::should_perform_init() { - JavaThread* THREAD = JavaThread::current(); - if (_state != initialized) { - if (THREAD == _initializingThread) { - return false; - } - MutexLocker locker(GraalInitialization_lock); - if (_state == uninitialized) { - _state = initializing; - _initializingThread = THREAD; - return true; - } else { - while (_state == initializing) { - GraalInitialization_lock->wait(); - } - } - } - return false; -} - -void GraalRuntime::initialize() { - if (!should_perform_init()) { - return; - } - +void GraalRuntime::initialize_natives(JNIEnv *env, jclass c2vmClass) { uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end(); uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024; AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)")); NOT_LP64(error("check TLAB allocation code for address space conflicts")); JavaThread* THREAD = JavaThread::current(); - ThreadToNativeFromVM trans(THREAD); - TRACE_graal_1("GraalRuntime::initialize"); - - JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment(); - jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl"); - if (klass == NULL) { - tty->print_cr("graal CompilerToVMImpl class not found"); - vm_abort(false); - } - env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count()); - - ResourceMark rm; - HandleMark hm; { - GRAAL_VM_ENTRY_MARK; - check_pending_exception("Could not register natives"); - } + ThreadToNativeFromVM trans(THREAD); - graal_compute_offsets(); - - // Ensure _non_oop_bits is initialized - Universe::non_oop_word(); - - { - GRAAL_VM_ENTRY_MARK; + ResourceMark rm; HandleMark hm; - VMToCompiler::initOptions(); - for (int i = 0; i < Arguments::num_graal_args(); ++i) { - const char* arg = Arguments::graal_args_array()[i]; - Handle option = java_lang_String::create_from_str(arg, THREAD); - jboolean result = VMToCompiler::setOption(option); - if (!result) { - tty->print_cr("Invalid option for graal: -G:%s", arg); - vm_abort(false); - } - } - VMToCompiler::finalizeOptions(CITime || CITimeEach); + + graal_compute_offsets(); _external_deopt_i2c_entry = create_external_deopt_i2c(); - VMToCompiler::startRuntime(); - - { - MutexLocker locker(GraalInitialization_lock); - _state = initialized; - _initializingThread = NULL; - } + // Ensure _non_oop_bits is initialized + Universe::non_oop_word(); -#if !defined(PRODUCT) && !defined(COMPILERGRAAL) - // In COMPILERGRAAL, we want to allow GraalBootstrap - // to happen first so GraalCompiler::initialize() - // duplicates the following code. - if (CompileTheWorld) { - VMToCompiler::compileTheWorld(); - } -#endif + env->RegisterNatives(c2vmClass, CompilerToVM_methods, CompilerToVM_methods_count()); } + check_pending_exception("Could not register natives"); } BufferBlob* GraalRuntime::initialize_buffer_blob() { @@ -703,14 +636,32 @@ } JRT_END -// JVM_InitializeGraalRuntime -JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass)) - GraalRuntime::initialize(); +// private static GraalRuntime Graal.initializeRuntime() +JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c)) return VMToCompiler::get_HotSpotGraalRuntime_jobject(); JVM_END -// JVM_InitializeTruffleRuntime -JVM_ENTRY(jobject, JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass)) - GraalRuntime::initialize(); +// private static TruffleRuntime Truffle.createRuntime() +JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c)) return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()()); JVM_END + +// private static void HotSpotGraalRuntime.init(Class compilerToVMClass) +JVM_ENTRY(void, JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass c2vmClass)) + GraalRuntime::initialize_natives(env, c2vmClass); +JVM_END + +// private static String[] HotSpotOptions.getVMOptions(boolean[] timeCompilations) +JVM_ENTRY(jobject, JVM_GetGraalOptions(JNIEnv *env, jclass c, jobject timeCompilations)) + HandleMark hm; + int numOptions = Arguments::num_graal_args(); + objArrayOop options = oopFactory::new_objArray(SystemDictionary::String_klass(), + numOptions, CHECK_NULL); + objArrayHandle optionsHandle(THREAD, options); + for (int i = 0; i < numOptions; i++) { + Handle option = java_lang_String::create_from_str(Arguments::graal_args_array()[i], CHECK_NULL); + optionsHandle->obj_at_put(i, option()); + } + ((typeArrayOop) JNIHandles::resolve(timeCompilations))->bool_at_put(0, CITime || CITimeEach); + return JNIHandles::make_local(THREAD, optionsHandle()); +JVM_END diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Tue May 13 02:31:41 2014 +0200 @@ -33,14 +33,9 @@ static address _external_deopt_i2c_entry; - enum State { uninitialized, initializing, initialized }; - static volatile State _state; - static Thread* _initializingThread; - static bool should_perform_init(); - public: - static /*synchronized*/ void initialize(); + static void initialize_natives(JNIEnv *env, jclass c2vmClass); static BufferBlob* initialize_buffer_blob(); static BasicType kindToBasicType(jchar ch); static address create_external_deopt_i2c(); diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/prims/jni.cpp Tue May 13 02:31:41 2014 +0200 @@ -35,6 +35,7 @@ #include "utilities/macros.hpp" #ifdef GRAAL #include "graal/graalCompiler.hpp" +#include "graal/graalVMToCompiler.hpp" #endif #if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" @@ -5210,7 +5211,19 @@ #endif // Check if we should compile all classes on bootclasspath +#ifdef GRAAL +#ifndef COMPILERGRAAL + if (CompileTheWorld) { + // Graal is considered as application code so we need to + // stop the VM deferring compilation now. + CompilationPolicy::completed_vm_startup(); + + VMToCompiler::compileTheWorld(); + } +#endif +#else if (CompileTheWorld) ClassLoader::compile_the_world(); +#endif if (ReplayCompiles) ciReplay::replay(thread); // Some platforms (like Win*) need a wrapper around these test diff -r 2d5f9c7379c1 -r 8df3b6d4a035 src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Tue May 13 02:31:20 2014 +0200 +++ b/src/share/vm/prims/nativeLookup.cpp Tue May 13 02:31:41 2014 +0200 @@ -124,8 +124,10 @@ void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass); void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass); #ifdef GRAAL - jobject JNICALL JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass); - jobject JNICALL JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass); + void JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass); + jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_GetGraalOptions(JNIEnv *env, jclass hotspotOptionsClass, jobject timeCompilations); #endif } @@ -138,8 +140,10 @@ { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) }, #ifdef GRAAL - { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_InitializeGraalRuntime) }, - { CC"Java_com_oracle_truffle_api_Truffle_initializeRuntime", NULL, FN_PTR(JVM_InitializeTruffleRuntime) }, + { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, + { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_getVMOptions", NULL, FN_PTR(JVM_GetGraalOptions) }, #endif };