# HG changeset patch # User Gilles Duboscq # Date 1357814470 -3600 # Node ID 4013a84e1dd00a860b85229b8cdd7966b881abee # Parent 9214756f9bbf5a2ee652d28ca211a11cbffeb2cc# Parent dd1b2da27b38df7acd8c5c2410cd12715395c2b3 Merge diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java --- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Thu Jan 10 11:41:10 2013 +0100 @@ -163,6 +163,16 @@ } curBit--; + if (cur.getBeginNode().probability() > 0.5) { + weight |= 1 << curBit; + } + curBit--; + + if (cur.getBeginNode().probability() > 0.05) { + weight |= 1 << curBit; + } + curBit--; + // guarantee that weight is > 0 weight |= 1; @@ -261,23 +271,26 @@ // start processing with standard entry block assert workList.isEmpty() : "list must be empty before processing"; - assert readyForProcessing(startBlock); sortIntoWorkList(startBlock); do { Block cur = workList.remove(workList.size() - 1); - appendBlock(cur); - - Node endNode = cur.getEndNode(); - if (endNode instanceof IfNode && ((IfNode) endNode).probability() < 0.5) { - assert cur.numberOfSux() == 2; - checkAndSortIntoWorkList(cur.suxAt(1)); - checkAndSortIntoWorkList(cur.suxAt(0)); - } else { - for (Block sux : cur.getSuccessors()) { - checkAndSortIntoWorkList(sux); - } - } + processBlock(cur); } while (workList.size() > 0); } + + private void processBlock(Block cur) { + appendBlock(cur); + + Node endNode = cur.getEndNode(); + if (endNode instanceof IfNode && ((IfNode) endNode).probability() < 0.5) { + assert cur.numberOfSux() == 2; + checkAndSortIntoWorkList(cur.suxAt(1)); + checkAndSortIntoWorkList(cur.suxAt(0)); + } else { + for (Block sux : cur.getSuccessors()) { + checkAndSortIntoWorkList(sux); + } + } + } } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LineNumberTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LineNumberTable.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,30 @@ +/* + * 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.api.meta; + + +public interface LineNumberTable { + int[] getLineNumberEntries(); + int[] getBciEntries(); + int getLineNumber(int bci); +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Thu Jan 10 11:41:10 2013 +0100 @@ -24,6 +24,7 @@ import java.lang.annotation.*; import java.lang.reflect.*; +import java.lang.reflect.Method; import java.util.*; /** @@ -159,4 +160,10 @@ * Returns {@code true} if this method can be inlined. */ boolean canBeInlined(); + + + /** + * Returns the LineNumberTable of this method. + */ + LineNumberTable getLineNumberTable(); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Jan 10 11:41:10 2013 +0100 @@ -241,4 +241,9 @@ * @return the field with the given offset, or {@code null} if there is no such field. */ ResolvedJavaField findInstanceFieldWithOffset(long offset); + + /** + * Returns name of source file of this type. + */ + String getSourceFileName(); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Jan 10 11:41:10 2013 +0100 @@ -42,6 +42,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.printer.*; /** * Base class for Graal compiler unit tests. @@ -68,7 +69,7 @@ protected final GraalCompiler graalCompiler; public GraalCompilerTest() { - Debug.enable(); + DebugEnvironment.initialize(System.out); this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); this.graalCompiler = Graal.getRequiredCapability(GraalCompiler.class); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java Thu Jan 10 11:41:10 2013 +0100 @@ -97,6 +97,7 @@ Debug.dump(graph, "Graph"); new ExpandBoxingNodesPhase(pool).apply(graph); new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); + new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); new CanonicalizerPhase(null, runtime(), assumptions).apply(referenceGraph); diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.compiler; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; +import com.oracle.graal.phases.*; + +/** + * Implements the filter specified by the {@link GraalOptions#Dump}, + * {@link GraalOptions#Log}, {@link GraalOptions#Meter} and {@link GraalOptions#Time} + * options. + *

+ * These options enable the associated debug facility if their filter + * matches the {@linkplain DebugScope#getQualifiedName() name} of the + * {@linkplain Debug#currentScope() current scope}. + *

+ * A filter is a list of comma-separated terms. Each term is interpreted + * as a glob pattern if it contains a "*" or "?" character. Otherwise, it is + * interpreted as a substring. If a term starts with "~", then it is an + * positive term. An input is matched by a filter if any of its positive + * terms match the input (or it has no positive terms) AND none of its + * negative terms match the input (or it has no negative terms). + *

+ * Examples of filters include: + *

+ *

+ */ +class DebugFilter { + + public static DebugFilter parse(String spec) { + if (spec == null) { + return null; + } + return new DebugFilter(spec.split(",")); + } + + final Term[] positive; + final Term[] negative; + + DebugFilter(String[] terms) { + List pos = new ArrayList<>(terms.length); + List neg = new ArrayList<>(terms.length); + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + if (t.startsWith("~")) { + neg.add(new Term(t.substring(1))); + } else { + pos.add(new Term(t)); + } + } + this.positive = pos.isEmpty() ? null : pos.toArray(new Term[pos.size()]); + this.negative = neg.isEmpty() ? null : neg.toArray(new Term[neg.size()]); + } + + /** + * Determines if a given input is matched by this filter. + */ + public boolean matches(String input) { + boolean match = true; + if (positive != null) { + match = false; + for (Term t : positive) { + if (t.matches(input)) { + match = true; + break; + } + } + } + if (match && negative != null) { + for (Term t : negative) { + if (t.matches(input)) { + match = false; + break; + } + } + } +// if (match) { +// System.out.println(this + " matches " + input); +// } + return match; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("DebugFilter["); + String sep = ""; + if (positive != null) { + buf.append(sep).append("pos=").append(Arrays.toString(positive)); + sep = ", "; + } + if (negative != null) { + buf.append(sep).append("neg=").append(Arrays.toString(negative)); + sep = ", "; + } + return buf.append("]").toString(); + } + + static class Term { + + final Pattern pattern; + + public Term(String filter) { + if (filter.isEmpty()) { + this.pattern = null; + } else if (filter.contains("*") || filter.contains("?")) { + this.pattern = Pattern.compile(MethodFilter.createGlobString(filter)); + } else { + this.pattern = Pattern.compile(".*" + MethodFilter.createGlobString(filter) + ".*"); + } + } + + /** + * Determines if a given input is matched by this filter. + */ + public boolean matches(String input) { + return pattern == null || pattern.matcher(input).matches(); + } + + @Override + public String toString() { + return pattern == null ? ".*" : pattern.toString(); + } + } +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jan 10 11:41:10 2013 +0100 @@ -168,7 +168,7 @@ if (GraalOptions.OptFloatingReads) { int mark = graph.getMark(); new FloatingReadPhase().apply(graph); - new CanonicalizerPhase(target, runtime, assumptions, mark).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph); if (GraalOptions.OptReadElimination) { new ReadEliminationPhase().apply(graph); } @@ -228,6 +228,7 @@ } }); + } public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final ResolvedJavaMethod method) { diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.compiler; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; + +public class GraalDebugConfig implements DebugConfig { + + private final DebugFilter logFilter; + private final DebugFilter meterFilter; + private final DebugFilter timerFilter; + private final DebugFilter dumpFilter; + private final MethodFilter[] methodFilter; + private final List dumpHandlers; + private final PrintStream output; + private final Set extraFilters = new HashSet<>(); + + public GraalDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output, List dumpHandlers) { + this.logFilter = DebugFilter.parse(logFilter); + this.meterFilter = DebugFilter.parse(meterFilter); + this.timerFilter = DebugFilter.parse(timerFilter); + this.dumpFilter = DebugFilter.parse(dumpFilter); + if (methodFilter == null || methodFilter.isEmpty()) { + this.methodFilter = null; + } else { + String[] filters = methodFilter.split(","); + this.methodFilter = new MethodFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + this.methodFilter[i] = new MethodFilter(filters[i]); + } + } + + // Report the filters that have been configured so the user can verify it's what they expect + if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) { + TTY.println(Thread.currentThread().getName() + ": " + toString()); + } + this.dumpHandlers = dumpHandlers; + this.output = output; + } + + public boolean isLogEnabled() { + return isEnabled(logFilter); + } + + public boolean isMeterEnabled() { + return isEnabled(meterFilter); + } + + public boolean isDumpEnabled() { + return isEnabled(dumpFilter); + } + + public boolean isTimeEnabled() { + return isEnabled(timerFilter); + } + + public PrintStream output() { + return output; + } + + private boolean isEnabled(DebugFilter filter) { + return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter(); + } + + private static boolean checkDebugFilter(String currentScope, DebugFilter filter) { + return filter != null && filter.matches(currentScope); + } + + private boolean checkMethodFilter() { + if (methodFilter == null && extraFilters.isEmpty()) { + return true; + } else { + for (Object o : Debug.context()) { + if (extraFilters.contains(o)) { + return true; + } else if (methodFilter != null) { + if (o instanceof JavaMethod) { + for (MethodFilter filter : methodFilter) { + if (filter.matches((JavaMethod) o)) { + return true; + } + } + } + } + } + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Debug config:"); + add(sb, "Log", logFilter); + add(sb, "Meter", meterFilter); + add(sb, "Time", timerFilter); + add(sb, "Dump", dumpFilter); + add(sb, "MethodFilter", methodFilter); + return sb.toString(); + } + + private static void add(StringBuilder sb, String name, Object filter) { + if (filter != null) { + sb.append(' '); + sb.append(name); + sb.append('='); + if (filter instanceof Object[]) { + sb.append(Arrays.toString((Object[]) filter)); + } else { + sb.append(String.valueOf(filter)); + } + } + } + + @Override + public RuntimeException interceptException(Throwable e) { + if (e instanceof BailoutException) { + return null; + } + Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output)); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); + for (Object o : Debug.context()) { + if (o instanceof Graph) { + Debug.log("Context obj %s", o); + if (GraalOptions.DumpOnError) { + Debug.dump(o, "Exception graph"); + } else { + Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); + } + } else if (o instanceof Node) { + String location = GraphUtil.approxSourceLocation((Node) o); + if (location != null) { + Debug.log("Context obj %s (approx. location: %s)", o, location); + } else { + Debug.log("Context obj %s", o); + } + } else { + Debug.log("Context obj %s", o); + } + } + return null; + } + + @Override + public Collection dumpHandlers() { + return dumpHandlers; + } + + @Override + public void addToContext(Object o) { + extraFilters.add(o); + } + + @Override + public void removeFromContext(Object o) { + extraFilters.remove(o); + } +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.compiler; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.api.meta.*; + +/** + * This class implements a method filter that can filter based on class name, method name and parameters. + * The syntax for the source pattern that is passed to the constructor is as follows: + * + *
+ * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] .
+ * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" .
+ * Class = { package "." } class .
+ * 
+ * + * + * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid filters are: + * + *
    + *
  • visit(Argument;BlockScope)
    + * Matches all methods named "visit", with the first parameter of type "Argument", and the second parameter of type "BlockScope". + * The packages of the parameter types are irrelevant.
  • + *
  • arraycopy(Object;;;;)
    + * Matches all methods named "arraycopy", with the first parameter of type "Object", and four more parameters of any type. + * The packages of the parameter types are irrelevant.
  • + *
  • com.oracle.graal.compiler.graph.PostOrderNodeIterator.*
    + * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".
  • + *
  • *
    + * Matches all methods in all classes
  • + *
  • com.oracle.graal.compiler.graph.*.visit
    + * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph". + *
+ */ +public class MethodFilter { + + private final Pattern clazz; + private final Pattern methodName; + private final Pattern[] signature; + + public MethodFilter(String sourcePattern) { + String pattern = sourcePattern.trim(); + + // extract parameter part + int pos = pattern.indexOf('('); + if (pos != -1) { + if (pattern.charAt(pattern.length() - 1) != ')') { + throw new IllegalArgumentException("missing ')' at end of method filter pattern: " + pattern); + } + String[] signatureClasses = pattern.substring(pos + 1, pattern.length() - 1).split(";", -1); + signature = new Pattern[signatureClasses.length]; + for (int i = 0; i < signatureClasses.length; i++) { + signature[i] = createClassGlobPattern(signatureClasses[i].trim()); + } + pattern = pattern.substring(0, pos); + } else { + signature = null; + } + + // If there is at least one "." then everything before the last "." is the class name. + // Otherwise, the pattern contains only the method name. + pos = pattern.lastIndexOf('.'); + if (pos != -1) { + clazz = createClassGlobPattern(pattern.substring(0, pos)); + methodName = Pattern.compile(createGlobString(pattern.substring(pos + 1))); + } else { + clazz = null; + methodName = Pattern.compile(createGlobString(pattern)); + } + } + + static String createGlobString(String pattern) { + return Pattern.quote(pattern).replace("?", "\\E.\\Q").replace("*", "\\E.*\\Q"); + } + + private static Pattern createClassGlobPattern(String pattern) { + if (pattern.length() == 0) { + return null; + } else if (pattern.contains(".")) { + return Pattern.compile(createGlobString(pattern)); + } else { + return Pattern.compile("([^\\.]*\\.)*" + createGlobString(pattern)); + } + } + + public boolean matches(JavaMethod o) { + // check method name first, since MetaUtil.toJavaName is expensive + if (methodName != null && !methodName.matcher(o.getName()).matches()) { + return false; + } + if (clazz != null && !clazz.matcher(MetaUtil.toJavaName(o.getDeclaringClass())).matches()) { + return false; + } + if (signature != null) { + Signature sig = o.getSignature(); + if (sig.getParameterCount(false) != signature.length) { + return false; + } + for (int i = 0; i < signature.length; i++) { + JavaType type = sig.getParameterType(i, null); + String javaName = MetaUtil.toJavaName(type); + if (signature[i] != null && !signature[i].matcher(javaName).matches()) { + return false; + } + } + } + return true; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("MethodFilter["); + String sep = ""; + if (clazz != null) { + buf.append(sep).append("clazz=").append(clazz); + sep = ", "; + } + if (methodName != null) { + buf.append(sep).append("methodName=").append(methodName); + sep = ", "; + } + if (signature != null) { + buf.append(sep).append("signature=").append(Arrays.toString(signature)); + sep = ", "; + } + return buf.append("]").toString(); + } +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Thu Jan 10 11:41:10 2013 +0100 @@ -25,8 +25,10 @@ import java.io.*; import java.util.concurrent.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.phases.*; +import com.oracle.graal.printer.*; public final class CompilerThread extends Thread { @@ -56,12 +58,10 @@ @Override public void run() { - HotSpotDebugConfig hotspotDebugConfig = null; + GraalDebugConfig hotspotDebugConfig = null; if (GraalOptions.Debug) { - Debug.enable(); PrintStream log = HotSpotGraalRuntime.getInstance().getVMToCompiler().log(); - hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log); - Debug.setConfig(hotspotDebugConfig); + DebugEnvironment.initialize(log); } try { super.run(); diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Jan 10 11:41:10 2013 +0100 @@ -200,4 +200,10 @@ long[] getDeoptedLeafGraphIds(); String decodePC(long pc); + + + long[] getLineNumberTable(HotSpotResolvedJavaMethod method); + + + String getFileName(HotSpotResolvedJavaType method); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Jan 10 11:41:10 2013 +0100 @@ -142,4 +142,10 @@ @Override public native String decodePC(long pc); + + @Override + public native long[] getLineNumberTable(HotSpotResolvedJavaMethod method); + + @Override + public native String getFileName(HotSpotResolvedJavaType method); } diff -r 9214756f9bbf -r 4013a84e1dd0 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 Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Jan 10 11:41:10 2013 +0100 @@ -44,6 +44,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.printer.*; import com.oracle.graal.snippets.*; /** @@ -123,10 +124,8 @@ } } - if (GraalOptions.Debug) { - Debug.enable(); - HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log); - Debug.setConfig(hotspotDebugConfig); + if (GraalOptions.Debug && GraalOptions.DebugSnippets) { + DebugEnvironment.initialize(log); } // Install intrinsics. GraalCompiler compiler = graalRuntime.getCompiler(); diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LineNumberTableImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LineNumberTableImpl.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,56 @@ +/* + * 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.hotspot.debug; + +import com.oracle.graal.api.meta.*; + + +public class LineNumberTableImpl implements LineNumberTable { + private final int[] lineNumbers; + private final int[] bci; + + public LineNumberTableImpl(int[] lineNumbers, int[] bci) { + this.lineNumbers = lineNumbers; + this.bci = bci; + } + + @Override + public int[] getLineNumberEntries() { + return lineNumbers; + } + + @Override + public int[] getBciEntries() { + return bci; + } + + @Override + public int getLineNumber(@SuppressWarnings("hiding") int bci) { + for (int i = 0; i < this.bci.length - 1; i++) { + if (this.bci[i] <= bci && bci < this.bci[i + 1]) { + return lineNumbers[i]; + } + } + return lineNumbers[lineNumbers.length - 1]; + } +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Jan 10 11:41:10 2013 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen; import com.oracle.graal.bytecode.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.phases.*; /** @@ -290,6 +291,21 @@ return HotSpotGraalRuntime.getInstance().getCompilerToVM().isMethodCompilable(metaspaceMethod); } + @Override + public LineNumberTable getLineNumberTable() { + long[] values = HotSpotGraalRuntime.getInstance().getCompilerToVM().getLineNumberTable(this); + assert values.length % 2 == 0; + int[] bci = new int[values.length / 2]; + int[] line = new int[values.length / 2]; + + for (int i = 0; i < values.length / 2; i++) { + bci[i] = (int) values[i * 2]; + line[i] = (int) values[i * 2 + 1]; + } + + return new LineNumberTableImpl(line, bci); + } + /** * Returns the offset of this method into the v-table. * If the holder is not initialized, returns -1 @@ -309,4 +325,5 @@ public CompilationTask currentTask() { return currentTask; } + } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Thu Jan 10 11:41:10 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType { @@ -33,4 +34,9 @@ } public abstract Class mirror(); + + @Override + public String getSourceFileName() { + return HotSpotGraalRuntime.getInstance().getCompilerToVM().getFileName(this); + } } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Thu Jan 10 11:41:10 2013 +0100 @@ -446,6 +446,11 @@ } @Override + public String getSourceFileName() { + return HotSpotGraalRuntime.getInstance().getCompilerToVM().getFileName(this); + } + + @Override public T getAnnotation(Class annotationClass) { return javaMirror.getAnnotation(annotationClass); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Thu Jan 10 11:41:10 2013 +0100 @@ -181,7 +181,12 @@ } @Override - public Class mirror() { + public String getSourceFileName() { + throw GraalInternalError.shouldNotReachHere(); + } + + @Override + public Class< ? > mirror() { return javaMirror; } } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Jan 10 11:41:10 2013 +0100 @@ -60,7 +60,7 @@ while (!loopBegin.isDeleted()) { int mark = graph.getMark(); peel(loop); - new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph); + new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph); if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) { throw new BailoutException("FullUnroll : Graph seems to grow out of proportion"); } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Jan 10 11:41:10 2013 +0100 @@ -358,10 +358,13 @@ PhiNode oldPhi = (PhiNode) oldMerge.usages().first(); PhiNode newPhi = graph().add(new PhiNode(oldPhi.stamp(), newMerge)); + double probability = 0.0; for (EndNode end : ends) { newPhi.addInput(phiValues.get(end)); newMerge.addForwardEnd(end); + probability += end.probability(); } + newMerge.setProbability(probability); FrameState stateAfter = oldMerge.stateAfter(); if (stateAfter != null) { diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Jan 10 11:41:10 2013 +0100 @@ -65,6 +65,33 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { + + if (source.isConstant()) { + Constant sourceConstant = source.asConstant(); + switch (sourceKind) { + case Boolean: + return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asBoolean()), tool.runtime(), graph()); + case Byte: + return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), tool.runtime(), graph()); + case Char: + return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), tool.runtime(), graph()); + case Short: + return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), tool.runtime(), graph()); + case Int: + return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), tool.runtime(), graph()); + case Long: + return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), tool.runtime(), graph()); + case Float: + return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), tool.runtime(), graph()); + case Double: + return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), tool.runtime(), graph()); + default: + assert false : "Unexpected source kind for boxing"; + break; + + } + } + for (Node usage : usages()) { if (usage != stateAfter()) { return this; diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Jan 10 11:41:10 2013 +0100 @@ -148,4 +148,13 @@ } return targetMethod().getName(); } + + public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) { + for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) { + if (target.targetMethod == method) { + return target; + } + } + return null; + } } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Jan 10 11:41:10 2013 +0100 @@ -186,30 +186,67 @@ /** * Gets an approximate source code location for a node if possible. * - * @return a file name and source line number in stack trace format (e.g. "String.java:32") - * if an approximate source location is found, null otherwise + * @return the StackTraceElements if an approximate source location is found, null otherwise */ - public static String approxSourceLocation(Node node) { + public static StackTraceElement[] approxSourceStackTraceElement(Node node) { + ArrayList elements = new ArrayList<>(); Node n = node; while (n != null) { if (n instanceof MethodCallTargetNode) { + elements.add(((MethodCallTargetNode) n).targetMethod().asStackTraceElement(-1)); n = ((MethodCallTargetNode) n).invoke().node(); } if (n instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) n).stateAfter(); - if (stateAfter != null) { - ResolvedJavaMethod method = stateAfter.method(); + FrameState state = ((StateSplit) n).stateAfter(); + while (state != null) { + ResolvedJavaMethod method = state.method(); if (method != null) { - StackTraceElement stackTraceElement = method.asStackTraceElement(stateAfter.bci); - if (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0) { - return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber(); - } + elements.add(method.asStackTraceElement(state.bci - 1)); } + state = state.outerFrameState(); } + break; } n = n.predecessor(); } + return elements.toArray(new StackTraceElement[elements.size()]); + } + + + /** + * Gets an approximate source code location for a node, encoded as an exception, if possible. + * + * @return the exception with the location + */ + public static RuntimeException approxSourceException(Node node, Throwable cause) { + final StackTraceElement[] elements = approxSourceStackTraceElement(node); + @SuppressWarnings("serial") + RuntimeException exception = new RuntimeException(cause.getMessage(), cause) { + + @Override + public synchronized Throwable fillInStackTrace() { + setStackTrace(elements); + return this; + } + }; + return exception; + } + + /** + * Gets an approximate source code location for a node if possible. + * + * @return a file name and source line number in stack trace format (e.g. "String.java:32") if an approximate source + * location is found, null otherwise + */ + public static String approxSourceLocation(Node node) { + StackTraceElement[] stackTraceElements = approxSourceStackTraceElement(node); + if (stackTraceElements != null && stackTraceElements.length > 0) { + StackTraceElement top = stackTraceElements[0]; + if (top.getFileName() != null && top.getLineNumber() >= 0) { + return top.getFileName() + ":" + top.getLineNumber(); + } + } return null; } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Jan 10 11:41:10 2013 +0100 @@ -50,14 +50,19 @@ private final TargetDescription target; private final Assumptions assumptions; private final MetaAccessProvider runtime; + private final CustomCanonicalizer customCanonicalizer; private final Iterable initWorkingSet; private NodeWorkList workList; private Tool tool; private List snapshotTemp; + public interface CustomCanonicalizer { + ValueNode canonicalize(Node node); + } + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions) { - this(target, runtime, assumptions, null, 0); + this(target, runtime, assumptions, null, 0, null); } /** @@ -65,24 +70,26 @@ * @param runtime * @param assumptions * @param workingSet the initial working set of nodes on which the canonicalizer works, should be an auto-grow node bitmap + * @param customCanonicalizer */ - public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet) { - this(target, runtime, assumptions, workingSet, 0); + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { + this(target, runtime, assumptions, workingSet, 0, customCanonicalizer); } /** * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by * this mark are processed otherwise all nodes in the graph are processed */ - public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark) { - this(target, runtime, assumptions, null, newNodesMark); + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + this(target, runtime, assumptions, null, newNodesMark, customCanonicalizer); } - public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, int newNodesMark) { + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { this.newNodesMark = newNodesMark; this.target = target; this.assumptions = assumptions; this.runtime = runtime; + this.customCanonicalizer = customCanonicalizer; this.initWorkingSet = workingSet; this.snapshotTemp = new ArrayList<>(); } @@ -127,7 +134,7 @@ int mark = graph.getMark(); if (!tryKillUnused(node)) { node.inputs().filter(GraphUtil.isFloatingNode()).snapshotTo(snapshotTemp); - if (!tryCanonicalize(node, graph, tool)) { + if (!tryCanonicalize(node, graph)) { tryInferStamp(node, graph); } else { for (Node in : snapshotTemp) { @@ -168,7 +175,19 @@ return false; } - public static boolean tryCanonicalize(final Node node, final StructuredGraph graph, final SimplifierTool tool) { + public boolean tryCanonicalize(final Node node, final StructuredGraph graph) { + boolean result = baseTryCanonicalize(node, graph); + if (!result && customCanonicalizer != null) { + ValueNode canonical = customCanonicalizer.canonicalize(node); + if (canonical == node && customCanonicalizer != null) { + canonical = customCanonicalizer.canonicalize(node); + } + result = performReplacement(node, graph, canonical); + } + return result; + } + + public boolean baseTryCanonicalize(final Node node, final StructuredGraph graph) { if (node instanceof Canonicalizable) { assert !(node instanceof Simplifiable); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); @@ -187,52 +206,9 @@ // Fixed-connected| 2 | X | 6 | // -------------------------------------------- // X: must not happen (checked with assertions) - if (canonical == node) { - Debug.log("Canonicalizer: work on %s", node); - return false; - } else { - Debug.log("Canonicalizer: replacing %s with %s", node, canonical); - METRIC_CANONICALIZED_NODES.increment(); - if (node instanceof FloatingNode) { - if (canonical == null) { - // case 1 - graph.removeFloating((FloatingNode) node); - } else { - // case 2 - assert !(canonical instanceof FixedNode) || (canonical.predecessor() != null || canonical instanceof StartNode || canonical instanceof MergeNode) : node + " -> " + canonical + - " : replacement should be floating or fixed and connected"; - graph.replaceFloating((FloatingNode) node, canonical); - } - } else { - assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; - FixedWithNextNode fixedWithNext = (FixedWithNextNode) node; + - // When removing a fixed node, new canonicalization opportunities for its successor may arise - assert fixedWithNext.next() != null; - tool.addToWorkList(fixedWithNext.next()); - - if (canonical == null) { - // case 3 - graph.removeFixed(fixedWithNext); - } else if (canonical instanceof FloatingNode) { - // case 4 - graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); - } else { - assert canonical instanceof FixedNode; - if (canonical.predecessor() == null) { - assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; - // case 5 - graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); - } else { - assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; - // case 6 - node.replaceAtUsages(canonical); - graph.removeFixed(fixedWithNext); - } - } - } - return true; - } + return performReplacement(node, graph, canonical); } }); } else if (node instanceof Simplifiable) { @@ -247,6 +223,55 @@ return node.isDeleted(); } + private boolean performReplacement(final Node node, final StructuredGraph graph, ValueNode canonical) { + if (canonical == node) { + Debug.log("Canonicalizer: work on %s", node); + return false; + } else { + Debug.log("Canonicalizer: replacing %s with %s", node, canonical); + METRIC_CANONICALIZED_NODES.increment(); + if (node instanceof FloatingNode) { + if (canonical == null) { + // case 1 + graph.removeFloating((FloatingNode) node); + } else { + // case 2 + assert !(canonical instanceof FixedNode) || (canonical.predecessor() != null || canonical instanceof StartNode || canonical instanceof MergeNode) : node + " -> " + canonical + + " : replacement should be floating or fixed and connected"; + graph.replaceFloating((FloatingNode) node, canonical); + } + } else { + assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; + FixedWithNextNode fixedWithNext = (FixedWithNextNode) node; + + // When removing a fixed node, new canonicalization opportunities for its successor may arise + assert fixedWithNext.next() != null; + tool.addToWorkList(fixedWithNext.next()); + + if (canonical == null) { + // case 3 + graph.removeFixed(fixedWithNext); + } else if (canonical instanceof FloatingNode) { + // case 4 + graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); + } else { + assert canonical instanceof FixedNode; + if (canonical.predecessor() == null) { + assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; + // case 5 + graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); + } else { + assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; + // case 6 + node.replaceAtUsages(canonical); + graph.removeFixed(fixedWithNext); + } + } + } + return true; + } + } + /** * Calls {@link ValueNode#inferStamp()} on the node and, if it returns true (which means that the stamp has * changed), re-queues the node's usages . If the stamp has changed then this method also checks if the stamp diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Jan 10 11:41:10 2013 +0100 @@ -32,11 +32,9 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.PhasePlan.PhasePosition; -import com.oracle.graal.phases.common.InliningUtil.InlineInfo; -import com.oracle.graal.phases.common.InliningUtil.InliningCallback; -import com.oracle.graal.phases.common.InliningUtil.InliningPolicy; -import com.oracle.graal.phases.common.InliningUtil.WeightComputationPolicy; +import com.oracle.graal.phases.PhasePlan.*; +import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; +import com.oracle.graal.phases.common.InliningUtil.*; public class InliningPhase extends Phase implements InliningCallback { /* @@ -52,6 +50,7 @@ private final Assumptions assumptions; private final GraphCache cache; private final InliningPolicy inliningPolicy; + private CustomCanonicalizer customCanonicalizer; // Metrics private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed"); @@ -63,6 +62,10 @@ this(target, runtime, assumptions, cache, plan, createInliningPolicy(assumptions, optimisticOpts, hints)); } + public void setCustomCanonicalizer(CustomCanonicalizer customCanonicalizer) { + this.customCanonicalizer = customCanonicalizer; + } + public InliningPhase(TargetDescription target, GraalCodeCacheProvider runtime, Assumptions assumptions, GraphCache cache, PhasePlan plan, InliningPolicy inliningPolicy) { this.target = target; this.runtime = runtime; @@ -90,7 +93,7 @@ Debug.dump(graph, "after %s", candidate); Iterable newNodes = graph.getNewNodes(mark); if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions, invokeUsages, mark).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, invokeUsages, mark, customCanonicalizer).apply(graph); } metricInliningPerformed.increment(); diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Jan 10 11:41:10 2013 +0100 @@ -886,7 +886,7 @@ * @param inlineGraph the graph that the invoke will be replaced with * @param receiverNullCheck true if a null check needs to be generated for non-static inlinings, false if no such check is required */ - public static void inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) { + public static Map inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) { NodeInputList parameters = invoke.callTarget().arguments(); StructuredGraph graph = (StructuredGraph) invoke.node().graph(); @@ -915,7 +915,7 @@ } } } - replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node())); // ensure proper anchoring of things that where anchored to the StartNode + replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node())); // ensure proper anchoring of things that were anchored to the StartNode assert invoke.node().successors().first() != null : invoke; assert invoke.node().predecessor() != null; @@ -1018,6 +1018,8 @@ invoke.node().replaceAtUsages(null); GraphUtil.killCFG(invoke.node()); + + return duplicates; } public static void receiverNullCheck(Invoke invoke) { diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Jan 10 11:41:10 2013 +0100 @@ -55,7 +55,7 @@ if (canonicalizationRoots.isEmpty()) { break; } - new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots, null).apply(graph); canonicalizationRoots.clear(); } } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Jan 10 11:41:10 2013 +0100 @@ -132,7 +132,7 @@ deferred = false; processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null, schedule, processed); Debug.dump(graph, "Lowering iteration %d", i++); - new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph); + new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph); if (!deferred && !containsLowerable(graph.getNewNodes(mark))) { // No new lowerable nodes - done! diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Jan 10 11:41:10 2013 +0100 @@ -121,6 +121,7 @@ // Debug settings: public static boolean Debug = true; + public static boolean DebugSnippets = false; public static boolean PerThreadDebugValues = ____; public static boolean SummarizeDebugValues = ____; public static boolean SummarizePerPhase = ____; diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Thu Jan 10 11:41:10 2013 +0100 @@ -0,0 +1,48 @@ +/* + * 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.printer; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.compiler.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.phases.*; + + +public class DebugEnvironment { + + public static void initialize(PrintStream log) { + Debug.enable(); + List dumpHandlers = new ArrayList<>(); + dumpHandlers.add(new GraphPrinterDumpHandler()); + if (GraalOptions.PrintCFG) { + if (GraalOptions.PrintBinaryGraphs) { + TTY.println("CFG dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it"); + } + dumpHandlers.add(new CFGPrinterObserver()); + } + GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log, dumpHandlers); + Debug.setConfig(hotspotDebugConfig); + } +} diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Thu Jan 10 11:41:10 2013 +0100 @@ -282,7 +282,7 @@ new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy); new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy); - new CanonicalizerPhase(null, runtime, assumptions, 0).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, assumptions, 0, null).apply(snippetCopy); } // Gather the template parameters @@ -340,7 +340,7 @@ LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); LoopTransformations.fullUnroll(loop, runtime, null); - new CanonicalizerPhase(null, runtime, assumptions, mark).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(snippetCopy); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Thu Jan 10 11:41:10 2013 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.CanonicalizerPhase.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.virtual.phases.ea.EffectList.Effect; @@ -42,6 +43,7 @@ private final TargetDescription target; private final MetaAccessProvider runtime; private final Assumptions assumptions; + private CustomCanonicalizer customCanonicalizer; private final boolean iterative; public PartialEscapeAnalysisPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, boolean iterative) { @@ -51,6 +53,10 @@ this.iterative = iterative; } + public void setCustomCanonicalizer(CustomCanonicalizer customCanonicalizer) { + this.customCanonicalizer = customCanonicalizer; + } + public static final void trace(String format, Object... obj) { if (GraalOptions.TraceEscapeAnalysis) { Debug.log(format, obj); @@ -108,7 +114,7 @@ return false; } if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, null, customCanonicalizer).apply(graph); } return true; } diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Thu Jan 10 11:41:10 2013 +0100 @@ -26,12 +26,12 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; -final class DefaultCallTarget extends CallTarget { +public class DefaultCallTarget extends CallTarget { protected final RootNode rootNode; protected final FrameDescriptor frameDescriptor; - DefaultCallTarget(RootNode function, FrameDescriptor frameDescriptor) { + protected DefaultCallTarget(RootNode function, FrameDescriptor frameDescriptor) { this.rootNode = function; this.frameDescriptor = frameDescriptor; } diff -r 9214756f9bbf -r 4013a84e1dd0 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 Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Thu Jan 10 11:41:10 2013 +0100 @@ -27,7 +27,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; -final class DefaultVirtualFrame implements VirtualFrame { +public final class DefaultVirtualFrame implements VirtualFrame { private static final Object UNDEFINED_OBJECT = null; private static final Boolean UNDEFINED_BOOLEAN = false; @@ -43,7 +43,7 @@ protected Object[] locals; protected Class[] tags; - DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { + public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { this.descriptor = descriptor; this.caller = caller; this.arguments = arguments; diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.truffle.codegen.processor/src/META-INF/services/javax.annotation.processing.Processor --- a/graal/com.oracle.truffle.codegen.processor/src/META-INF/services/javax.annotation.processing.Processor Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/META-INF/services/javax.annotation.processing.Processor Thu Jan 10 11:41:10 2013 +0100 @@ -1,1 +1,1 @@ -com.oracle.truffle.codegen.processor.TruffleProcessor \ No newline at end of file +com.oracle.truffle.codegen.processor.TruffleProcessor diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame Thu Jan 10 11:41:10 2013 +0100 @@ -46,7 +46,7 @@ public final Scanner scanner; public final Errors errors; private final NodeFactory factory; - -->declarations + -->declarations public Parser(Scanner scanner, NodeFactory factory) { this.scanner = scanner; this.factory = factory; diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame Thu Jan 10 11:41:10 2013 +0100 @@ -403,7 +403,7 @@ NextCh(); } } - + -->comments void CheckLiteral() { @@ -418,7 +418,7 @@ Token NextToken() { while (ch == ' ' || -->scan1 - ) NextCh(); + ) NextCh(); -->scan2 int recKind = noSym; int recEnd = pos; diff -r 9214756f9bbf -r 4013a84e1dd0 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Thu Jan 10 11:40:25 2013 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Thu Jan 10 11:41:10 2013 +0100 @@ -28,7 +28,7 @@ = Function { - Function + Function } . @@ -86,7 +86,7 @@ } ";" (. result = factory.createPrint(expressions); .) . - + ReturnStatement = "return" @@ -97,8 +97,8 @@ = ValueExpression [ - ("<" | ">" | "<=" | ">=" | "==" | "!=" ) (. String op = t.val; .) - ValueExpression (. result = factory.createBinary(op, result, right); .) + ("<" | ">" | "<=" | ">=" | "==" | "!=" ) (. String op = t.val; .) + ValueExpression (. result = factory.createBinary(op, result, right); .) ] . diff -r 9214756f9bbf -r 4013a84e1dd0 mx/projects --- a/mx/projects Thu Jan 10 11:40:25 2013 +0100 +++ b/mx/projects Thu Jan 10 11:41:10 2013 +0100 @@ -237,7 +237,7 @@ # graal.compiler.test project@com.oracle.graal.compiler.test@subDir=graal project@com.oracle.graal.compiler.test@sourceDirs=src -project@com.oracle.graal.compiler.test@dependencies=JUNIT,com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.api.runtime +project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.printer,JUNIT project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.test@javaCompliance=1.7 diff -r 9214756f9bbf -r 4013a84e1dd0 src/cpu/x86/vm/jniTypes_x86.hpp --- a/src/cpu/x86/vm/jniTypes_x86.hpp Thu Jan 10 11:40:25 2013 +0100 +++ b/src/cpu/x86/vm/jniTypes_x86.hpp Thu Jan 10 11:41:10 2013 +0100 @@ -128,11 +128,25 @@ static inline jfloat get_float (intptr_t *from) { return *(jfloat *) from; } static inline jdouble get_double(intptr_t *from) { return *(jdouble *)(from + _JNI_SLOT_OFFSET); } - static inline jint get_int (intptr_t *from, int& pos) { return get_int(from + pos++); } - static inline jlong get_long (intptr_t *from, int& pos) { return get_long(from + pos); pos += 2; } - static inline oop get_obj (intptr_t *from, int& pos) { return get_obj(from + pos++); } - static inline jfloat get_float (intptr_t *from, int& pos) { return get_float(from + pos++); } - static inline jdouble get_double(intptr_t *from, int& pos) { return get_double(from + pos); pos += 2; } + static inline jint get_int (intptr_t *from, int& pos) { + return get_int(from + pos++); + } + static inline jlong get_long (intptr_t *from, int& pos) { + jlong result = get_long(from + pos); + pos += 2; + return result; + } + static inline oop get_obj (intptr_t *from, int& pos) { + return get_obj(from + pos++); + } + static inline jfloat get_float (intptr_t *from, int& pos) { + return get_float(from + pos++); + } + static inline jdouble get_double(intptr_t *from, int& pos) { + jdouble result = get_double(from + pos); + pos += 2; + return result; + } #undef _JNI_SLOT_OFFSET }; diff -r 9214756f9bbf -r 4013a84e1dd0 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Jan 10 11:40:25 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Jan 10 11:41:10 2013 +0100 @@ -938,6 +938,47 @@ return JNIHandles::make_local(result()); C2V_END +C2V_ENTRY(jlongArray, getLineNumberTable, (JNIEnv *env, jobject, jobject hotspot_method)) +// XXX: Attention: it seEms that the line number table of a method just contains lines that are important, means that +// empty lines are left out or lines that can't have a breakpoint on it; eg int a; or try { + Method* method = getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method)); + if(!method->has_linenumber_table()) { + return NULL; + } + u2 num_entries = 0; + CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table()); + while (streamForSize.read_pair()) { + num_entries++; + } + + CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); + jlongArray result = env->NewLongArray(2 * num_entries); + + int i = 0; + jlong value; + while (stream.read_pair()) { + value = ((long) stream.bci()); + env->SetLongArrayRegion(result,i,1,&value); + value = ((long) stream.line()); + env->SetLongArrayRegion(result,i + 1,1,&value); + i += 2; + } + + return result; +C2V_END + + +C2V_VMENTRY(jobject, getFileName, (JNIEnv *, jobject, jobject klass)) + ResourceMark rm; + InstanceKlass* k = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(klass)); + Symbol *s = k->source_file_name(); + int length; + jchar *name = s->as_unicode(length); + + Handle result = java_lang_String::create_from_unicode(name, length, CHECK_NULL); + return JNIHandles::make_local(result()); + +C2V_END #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -960,6 +1001,7 @@ #define CLASS "Ljava/lang/Class;" #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define HS_RESOLVED_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;" +#define HS_RESOLVED_JAVA_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;" #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" #define HS_RESOLVED_FIELD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;" #define HS_COMP_RESULT "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;" @@ -1008,6 +1050,8 @@ {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, {CC"getDeoptedLeafGraphIds", CC"()[J", FN_PTR(getDeoptedLeafGraphIds)}, {CC"decodePC", CC"(J)"STRING, FN_PTR(decodePC)}, + {CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)}, + {CC"getFileName", CC"("HS_RESOLVED_JAVA_TYPE")"STRING, FN_PTR(getFileName)}, }; int CompilerToVM_methods_count() {