# HG changeset patch # User Andreas Woess # Date 1385988365 -3600 # Node ID b96cc3b87e874cd42f0eb471938a3d7a525b5e18 # Parent bef512e4226226e6ac6e5d4e5bc136572b301037# Parent 66d793d064654c6ad3031d26cc5cd0a17a079ef5 Merge diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Sat Nov 30 18:41:35 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Mon Dec 02 13:46:05 2013 +0100 @@ -98,7 +98,9 @@ } } else if (barrierType == BarrierType.IMPRECISE) { if (useG1GC()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + if (!node.isInitialization()) { + addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + } addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); } else { addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Sat Nov 30 18:41:35 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Mon Dec 02 13:46:05 2013 +0100 @@ -239,7 +239,9 @@ int slotIndex = slot.getIndex(); if (slotIndex >= getTags().length) { CompilerDirectives.transferToInterpreter(); - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } getTags()[slotIndex] = (byte) accessKind.ordinal(); } @@ -248,7 +250,9 @@ int slotIndex = slot.getIndex(); if (slotIndex >= getTags().length) { CompilerDirectives.transferToInterpreter(); - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } byte tag = this.getTags()[slotIndex]; if (tag != accessKind.ordinal()) { @@ -289,7 +293,7 @@ } } - private void resize() { + private boolean resize() { int oldSize = tags.length; int newSize = descriptor.getSize(); if (newSize > oldSize) { @@ -297,7 +301,9 @@ Arrays.fill(locals, oldSize, newSize, descriptor.getTypeConversion().getDefaultValue()); primitiveLocals = Arrays.copyOf(primitiveLocals, newSize); tags = Arrays.copyOf(tags, newSize); + return true; } + return false; } private byte getTag(FrameSlot slot) { diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Sat Nov 30 18:41:35 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Dec 02 13:46:05 2013 +0100 @@ -80,7 +80,6 @@ this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess()); this.cache = runtime.getGraphCache(); this.truffleCache = truffleCache; - try { executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class)); } catch (NoSuchMethodException ex) { @@ -180,6 +179,10 @@ private void expandTree(StructuredGraph graph, Assumptions assumptions) { PhaseContext phaseContext = new PhaseContext(providers, assumptions); + TruffleExpansionLogger expansionLogger = null; + if (TraceTruffleExpansion.getValue()) { + expansionLogger = new TruffleExpansionLogger(graph); + } boolean changed; do { changed = false; @@ -210,7 +213,13 @@ if (inlineGraph != null) { int nodeCountBefore = graph.getNodeCount(); Mark mark = graph.getMark(); - InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false); + if (TraceTruffleExpansion.getValue()) { + expansionLogger.preExpand(methodCallTargetNode, inlineGraph); + } + Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false); + if (TraceTruffleExpansion.getValue()) { + expansionLogger.postExpand(inlined); + } if (Debug.isDumpEnabled()) { int nodeCountAfter = graph.getNodeCount(); Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); @@ -229,6 +238,10 @@ } } } while (changed); + + if (TraceTruffleExpansion.getValue()) { + expansionLogger.print(); + } } private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final Assumptions assumptions, final PhaseContext phaseContext) { diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Sat Nov 30 18:41:35 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Dec 02 13:46:05 2013 +0100 @@ -82,6 +82,10 @@ @Option(help = "") public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false); @Option(help = "") + public static final OptionValue TraceTruffleExpansion = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue TraceTruffleExpansionSource = new OptionValue<>(false); + @Option(help = "") public static final OptionValue TraceTruffleCacheDetails = new OptionValue<>(false); @Option(help = "") public static final OptionValue TraceTruffleCompilationExceptions = new OptionValue<>(true); diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Mon Dec 02 13:46:05 2013 +0100 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; +import java.util.Map.Entry; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; + +public class TruffleExpansionLogger { + + private final ExpansionTree root; + private final Map callToParentTree = new HashMap<>(); + + public TruffleExpansionLogger(StructuredGraph graph) { + root = new ExpansionTree(null, null, graph.method(), -1); + registerParentInCalls(root, graph); + } + + public void preExpand(MethodCallTargetNode callTarget, StructuredGraph inliningGraph) { + ResolvedJavaMethod sourceMethod = callTarget.invoke().getState().method(); + + int sourceMethodBci = callTarget.invoke().bci(); + ResolvedJavaMethod targetMethod = callTarget.targetMethod(); + Object targetReceiver = null; + if (!Modifier.isStatic(sourceMethod.getModifiers())) { + targetReceiver = callTarget.arguments().first().asConstant().asObject(); + } + + ExpansionTree parent = callToParentTree.get(callTarget); + assert parent != null; + callToParentTree.remove(callTarget); + ExpansionTree tree = new ExpansionTree(parent, targetReceiver, targetMethod, sourceMethodBci); + registerParentInCalls(tree, inliningGraph); + } + + @SuppressWarnings("unchecked") + public void postExpand(Map states) { + Iterable> entries; + if (states instanceof NodeMap) { + entries = ((NodeMap) states).entries(); + } else { + entries = states.entrySet(); + } + + for (Entry entry : entries) { + Node key = entry.getKey(); + Node value = entry.getValue(); + + if (value instanceof MethodCallTargetNode && callToParentTree.containsKey(key)) { + callToParentTree.put((MethodCallTargetNode) value, callToParentTree.get(key)); + callToParentTree.remove(key); + } + } + } + + private void registerParentInCalls(ExpansionTree parentTree, StructuredGraph graph) { + for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) { + callToParentTree.put(target, parentTree); + } + } + + public void print() { + root.print(System.out); + } + + private static final class ExpansionTree implements Comparable { + + private final ExpansionTree parent; + private final Object targetReceiver; + private final ResolvedJavaMethod targetMethod; + private final int parentBci; + private final List children = new ArrayList<>(); + + public ExpansionTree(ExpansionTree parent, Object receiver, ResolvedJavaMethod targetMethod, int parentBci) { + this.parent = parent; + this.targetReceiver = receiver; + this.targetMethod = targetMethod; + this.parentBci = parentBci; + if (parent != null) { + parent.children.add(this); + } + } + + public int compareTo(ExpansionTree o) { + if (parent == o.parent) { + return parentBci - o.parentBci; + } + return 0; + } + + public void print(PrintStream p) { + print(p, ""); + } + + private void print(PrintStream p, String indent) { + StackTraceElement targetElement = targetMethod.asStackTraceElement(0); + StackTraceElement sourceElement = null; + + ExpansionTree currentParent = this.parent; + if (currentParent != null) { + sourceElement = currentParent.targetMethod.asStackTraceElement(parentBci); + } + + String className = targetElement.getClassName(); + int lastIndex = className.lastIndexOf('.'); + if (lastIndex != -1) { + className = className.substring(lastIndex + 1, className.length()); + } + + lastIndex = className.lastIndexOf('$'); + if (lastIndex != -1) { + className = className.substring(lastIndex + 1, className.length()); + } + + String constantType = ""; + if (targetReceiver != null) { + if (!targetReceiver.getClass().getSimpleName().equals(className)) { + constantType = "<" + targetReceiver.getClass().getSimpleName() + ">"; + } + } + + String sourceSource = ""; + String targetSource = ""; + if (TruffleCompilerOptions.TraceTruffleExpansionSource.getValue()) { + sourceSource = formatSource(sourceElement); + targetSource = formatSource(targetElement); + } + p.printf("%s%s %s%s.%s%s%n", indent, sourceSource, className, constantType, targetMethod.getName(), targetSource); + + Collections.sort(children); + + for (ExpansionTree child : children) { + child.print(p, indent + " "); + } + } + + private static String formatSource(StackTraceElement e) { + if (e == null) { + return ""; + } + if (e.getFileName() != null) { + if (e.getLineNumber() >= 0) { + return String.format("(%s:%d)", e.getFileName(), e.getLineNumber()); + } else { + return String.format("(%s)", e.getFileName(), e.getLineNumber()); + } + } else { + return String.format("(Unknown Source)", e.getFileName(), e.getLineNumber()); + } + } + } + +} diff -r 66d793d06465 -r b96cc3b87e87 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Sat Nov 30 18:41:35 2013 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Mon Dec 02 13:46:05 2013 +0100 @@ -160,7 +160,9 @@ public Object getValue(FrameSlot slot) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } return locals[slotIndex]; } @@ -168,7 +170,9 @@ private void verifySet(FrameSlot slot, FrameSlotKind accessKind) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } tags[slotIndex] = (byte) accessKind.ordinal(); } @@ -176,7 +180,9 @@ private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } byte tag = tags[slotIndex]; if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) { @@ -190,20 +196,24 @@ } } - private void resize() { + private boolean resize() { int oldSize = tags.length; int newSize = descriptor.getSize(); if (newSize > oldSize) { locals = Arrays.copyOf(locals, newSize); Arrays.fill(locals, oldSize, newSize, descriptor.getTypeConversion().getDefaultValue()); tags = Arrays.copyOf(tags, newSize); + return true; } + return false; } private byte getTag(FrameSlot slot) { int slotIndex = slot.getIndex(); if (slotIndex >= tags.length) { - resize(); + if (!resize()) { + throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); + } } return tags[slotIndex]; }