# HG changeset patch # User Thomas Wuerthinger # Date 1331207179 -3600 # Node ID 90c150a0a22b9da3fb75b476bd8fb8481a1b1b7f # Parent b4f548d49f965b2776bea3e9075944d64607dfa3# Parent c53115427ff9ade451ac97a6ce1ef92989cbe292 Merge. diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Thu Mar 08 12:46:19 2012 +0100 @@ -129,6 +129,7 @@ // Other printing settings public static boolean PrintQueue = ____; public static boolean PrintCompilation = ____; + public static boolean PrintProfilingInformation = ____; public static boolean PrintXirTemplates = ____; public static boolean PrintIRWithLIR = ____; public static boolean PrintAssembly = ____; diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Mar 08 12:46:19 2012 +0100 @@ -33,6 +33,7 @@ import com.oracle.max.graal.compiler.util.InliningUtil.InliningCallback; import com.oracle.max.graal.cri.*; import com.oracle.max.graal.debug.*; +import com.oracle.max.graal.debug.internal.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -245,14 +246,13 @@ private static class WeightBasedInliningPolicy implements InliningPolicy { @Override public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - Debug.log("not inlining (CompiledCodeSize too large %d): %s", info.compiledCodeSize(), info); + if (!checkCompiledCodeSize(info)) { return false; } double penalty = Math.pow(GraalOptions.InliningSizePenaltyExp, callerGraph.getNodeCount() / (double) GraalOptions.MaximumDesiredSize) / GraalOptions.InliningSizePenaltyExp; if (info.weight > GraalOptions.MaximumInlineWeight / (1 + penalty * GraalOptions.InliningSizePenalty)) { - Debug.log("not inlining (cut off by weight %e): ", info.weight); + Debug.log("not inlining (cut off by weight %e): %s", info.weight, info); return false; } @@ -265,13 +265,7 @@ @Override public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { double maxSize = Math.max(GraalOptions.MaximumTrivialSize, Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize); - if (info.weight <= maxSize) { - Debug.log("inlining (size %f): %s", info.weight, info); - return true; - } else { - Debug.log("not inlining (too large %f): %s", info.weight, info); - return false; - } + return decideSizeBasedInlining(info, maxSize); } } @@ -279,8 +273,7 @@ @Override public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - Debug.log("not inlining (CompiledCodeSize too large %d): %s", info.compiledCodeSize(), info); + if (!checkCompiledCodeSize(info)) { return false; } @@ -288,13 +281,7 @@ double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize * inlineWeight; maxSize = Math.max(GraalOptions.MaximumTrivialSize, maxSize); - if (info.weight <= maxSize) { - Debug.log("inlining (size %f <= %f): %s", info.weight, maxSize, info); - return true; - } else { - Debug.log("not inlining (too large %f > %f): %s", info.weight, maxSize, info); - return false; - } + return decideSizeBasedInlining(info, maxSize); } } @@ -302,8 +289,7 @@ @Override public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - Debug.log("not inlining (CompiledCodeSize too large %d): %s", info.compiledCodeSize(), info); + if (!checkCompiledCodeSize(info)) { return false; } @@ -312,13 +298,7 @@ maxSize = maxSize + maxSize * inlineBoost; maxSize = Math.min(GraalOptions.MaximumGreedyInlineSize, Math.max(GraalOptions.MaximumTrivialSize, maxSize)); - if (info.weight <= maxSize) { - Debug.log("inlining (size %f <= %f): %s", info.weight, maxSize, info); - return true; - } else { - Debug.log("not inlining (too large %f > %f): %s", info.weight, maxSize, info); - return false; - } + return decideSizeBasedInlining(info, maxSize); } } @@ -326,8 +306,7 @@ @Override public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - Debug.log("not inlining (CompiledCodeSize too large %d): %s", info.compiledCodeSize(), info); + if (!checkCompiledCodeSize(info)) { return false; } @@ -345,16 +324,28 @@ maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * maxSize * inlineRatio; maxSize = Math.max(maxSize, GraalOptions.MaximumTrivialSize); - if (info.weight <= maxSize) { - Debug.log("inlining (size %f <= %f): %s", info.weight, maxSize, info); - return true; - } else { - Debug.log("not inlining (too large %f > %f): %s", info.weight, maxSize, info); - return false; - } + return decideSizeBasedInlining(info, maxSize); } } + private static boolean decideSizeBasedInlining(InlineInfo info, double maxSize) { + boolean success = info.weight <= maxSize; + if (DebugScope.getInstance().isLogEnabled()) { + String formatterString = success ? "inlining invoke at %s@%d (size %f <= %f): %s" : "not inlining invoke at %s@%d (too large %f > %f): %s"; + Debug.log(formatterString, CiUtil.format("%H.%n(%p):%r", info.invoke.stateAfter().method()), info.invoke.bci(), info.weight, maxSize, info); + } + return success; + } + + private static boolean checkCompiledCodeSize(InlineInfo info) { + if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { + Debug.log("not inlining invoke at %s@%d (CompiledCodeSize %d > %d): %s", CiUtil.format("%H.%n(%p):%r", info.invoke.stateAfter().method()), info.invoke.bci(), info.compiledCodeSize(), GraalOptions.SmallCompiledCodeSize, info); + return false; + } + return true; + } + + private interface WeightComputationPolicy { double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke); } diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.examples/src/examples/HelloWorld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/examples/HelloWorld.java Thu Mar 08 12:46:19 2012 +0100 @@ -0,0 +1,30 @@ +/* + * 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 examples; + + +public class HelloWorld { + public static void main(String[] args) { + System.out.println("hello world!"); + } +} diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotDebugConfig.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotDebugConfig.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotDebugConfig.java Thu Mar 08 12:46:19 2012 +0100 @@ -48,7 +48,11 @@ this.timerFilter = timerFilter; this.dumpFilter = dumpFilter; this.methodFilter = methodFilter == null ? null : methodFilter.split(","); - dumpHandlers.add(new IdealGraphPrinterDumpHandler(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort)); + if (GraalOptions.PrintIdealGraphFile) { + dumpHandlers.add(new IdealGraphPrinterDumpHandler()); + } else { + dumpHandlers.add(new IdealGraphPrinterDumpHandler(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort)); + } dumpHandlers.add(new CFGPrinterObserver()); } diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java Thu Mar 08 12:46:19 2012 +0100 @@ -302,7 +302,7 @@ @Override public double getBranchTakenProbability(HotSpotMethodData data, int position) { - return 1; + return getExecutionCount(data, position) != 0 ? 1 : 0; } @Override diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Thu Mar 08 12:46:19 2012 +0100 @@ -238,6 +238,7 @@ return ((HotSpotTypeResolvedImpl) holder()).constantPool(); } + @Override public void dumpProfile() { TTY.println("profile info for %s", this); TTY.println("canBeStaticallyBound: " + canBeStaticallyBound()); diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java Thu Mar 08 12:46:19 2012 +0100 @@ -457,6 +457,7 @@ block.successors.add(block.retSuccessor); assert block.retSuccessor != block.jsrSuccessor; } + Debug.log("JSR alternatives block %s sux %s jsrSux %s retSux %s jsrScope %s", block, block.successors, block.jsrSuccessor, block.retSuccessor, block.jsrScope); if (block.jsrSuccessor != null || !scope.isEmpty()) { for (int i = 0; i < block.successors.size(); i++) { @@ -468,7 +469,7 @@ if (successor == block.retSuccessor) { nextScope = scope.pop(); } - if (!successor.jsrScope.isEmpty()) { + if (!successor.jsrScope.isPrefixOf(nextScope)) { throw new JsrNotSupportedBailout("unstructured control flow (" + successor.jsrScope + " " + nextScope + ")"); } if (!nextScope.isEmpty()) { diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Thu Mar 08 12:46:19 2012 +0100 @@ -152,6 +152,10 @@ log.println("Compiling " + method); } + if (GraalOptions.PrintProfilingInformation) { + method.dumpProfile(); + } + // compute the block map, setup exception handlers and get the entrypoint(s) BciBlockMapping blockMap = createBlockMap(); this.canTrapBitSet = blockMap.canTrap; @@ -531,7 +535,11 @@ } private void genGoto() { - appendGoto(createTarget(currentBlock.successors.get(0), frameState)); + double probability = profilingInfo.getBranchTakenProbability(bci()); + if (probability < 0) { + probability = 1; + } + appendGoto(createTarget(probability, currentBlock.successors.get(0), frameState)); assert currentBlock.normalSuccessors == 1; } @@ -1188,6 +1196,15 @@ return x; } + private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { + assert probability >= 0 && probability <= 1; + if (probability == 0 && config.useBranchPrediction()) { + return currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile)); + } else { + return createTarget(block, stateAfter); + } + } + private FixedNode createTarget(Block block, FrameStateBuilder stateAfter) { assert block != null && stateAfter != null; assert !block.isExceptionEntry || stateAfter.stackSize() == 1; @@ -1255,22 +1272,13 @@ * deoptimizes immediately. */ private BeginNode createBlockTarget(double probability, Block block, FrameStateBuilder stateAfter) { - assert probability >= 0 && probability <= 1; - if (probability == 0) { - FrameStateBuilder state = stateAfter.copy(); - state.clearNonLiveLocals(block.localsLiveIn); - - BeginNode begin = currentGraph.add(new BeginNode()); - DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile)); - begin.setNext(deopt); - begin.setStateAfter(state.create(block.startBci)); - return begin; - } - - FixedNode target = createTarget(block, stateAfter); + FixedNode target = createTarget(probability, block, stateAfter); assert !(target instanceof BeginNode); BeginNode begin = currentGraph.add(new BeginNode()); begin.setNext(target); + + assert !(target instanceof DeoptimizeNode && begin.stateAfter() != null) : + "We are not allowed to set the stateAfter of the begin node, because we have to deoptimize to a bci _before_ the actual if, so that the interpreter can update the profiling information."; return begin; } diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java Thu Mar 08 12:46:19 2012 +0100 @@ -51,6 +51,10 @@ return scope == 0; } + public boolean isPrefixOf(JsrScope other) { + return (scope & other.scope) == scope; + } + public JsrScope pop() { return new JsrScope(scope >>> 16); } diff -r b4f548d49f96 -r 90c150a0a22b graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java --- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java Thu Mar 08 12:45:49 2012 +0100 +++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java Thu Mar 08 12:46:19 2012 +0100 @@ -69,31 +69,37 @@ return result; } - private void test(String snippet) { - StructuredGraph graph = parse(snippet); - BoxingMethodPool pool = new BoxingMethodPool(runtime()); - IdentifyBoxingPhase identifyBoxingPhase = new IdentifyBoxingPhase(pool); - PhasePlan phasePlan = getDefaultPhasePlan(); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, identifyBoxingPhase); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PhiStampPhase()); - identifyBoxingPhase.apply(graph); - Collection hints = new ArrayList<>(); - for (Invoke invoke : graph.getInvokes()) { - hints.add(invoke); - } - new InliningPhase(null, runtime(), hints, null, phasePlan).apply(graph); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - new PhiStampPhase().apply(graph); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - Debug.dump(graph, "Graph"); - new BoxingEliminationPhase().apply(graph); - Debug.dump(graph, "Graph"); - new ExpandBoxingNodesPhase(pool).apply(graph); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - new DeadCodeEliminationPhase().apply(graph); - StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); - new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph); - new DeadCodeEliminationPhase().apply(referenceGraph); - assertEquals(referenceGraph, graph); + private void test(final String snippet) { + Debug.scope("IfBoxingEliminationTest", new DebugDumpScope(snippet), new Runnable() { + @Override + public void run() { + StructuredGraph graph = parse(snippet); + BoxingMethodPool pool = new BoxingMethodPool(runtime()); + IdentifyBoxingPhase identifyBoxingPhase = new IdentifyBoxingPhase(pool); + PhasePlan phasePlan = getDefaultPhasePlan(); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, identifyBoxingPhase); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PhiStampPhase()); + identifyBoxingPhase.apply(graph); + Collection hints = new ArrayList<>(); + for (Invoke invoke : graph.getInvokes()) { + hints.add(invoke); + } + new InliningPhase(null, runtime(), hints, null, phasePlan).apply(graph); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + new PhiStampPhase().apply(graph); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + Debug.dump(graph, "Graph"); + new BoxingEliminationPhase().apply(graph); + Debug.dump(graph, "Graph"); + new ExpandBoxingNodesPhase(pool).apply(graph); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + new DeadCodeEliminationPhase().apply(graph); + StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); + new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph); + new DeadCodeEliminationPhase().apply(referenceGraph); + + assertEquals(referenceGraph, graph); + } + }); } } diff -r b4f548d49f96 -r 90c150a0a22b mx/commands.py --- a/mx/commands.py Thu Mar 08 12:45:49 2012 +0100 +++ b/mx/commands.py Thu Mar 08 12:46:19 2012 +0100 @@ -29,6 +29,7 @@ import os, sys, shutil, zipfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing from os.path import join, exists, dirname, basename from argparse import ArgumentParser, REMAINDER +from threading import Thread import mx import sanitycheck import json @@ -230,6 +231,17 @@ if len(failed) != 0: mx.abort('DaCapo failures: ' + str(failed)) +def intro(args): + """"run a simple program and visualize its compilation in the Graal Visualizer""" + # Start the visualizer in a separate thread + t = Thread(target=gv, args=([[]])) + t.start() + + # Give visualizer time to start + mx.log('Waiting 5 seconds for visualizer to start') + time.sleep(5) + + vm(['-G:Dump=HelloWorld', '-G:MethodFilter=main', '-Xcomp', '-XX:CompileOnly=HelloWorld::main', '-cp', mx.classpath('com.oracle.max.graal.examples')] + args + ['examples.HelloWorld']) def scaladacapo(args): """run one or all Scala DaCapo benchmarks @@ -484,8 +496,8 @@ build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product' mx.expand_project_in_args(args) - if mx.java().debug: - args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000'] + args + if mx.java().debug_port is not None: + args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(mx.java().debug_port)] + args if _jacoco == 'on' or _jacoco == 'append': jacocoagent = mx.library("JACOCOAGENT", True) agentOptions = { @@ -646,6 +658,7 @@ parser = ArgumentParser(prog='mx gate'); parser.add_argument('-n', '--omit-native-build', action='store_false', dest='buildNative', help='omit cleaning and building native code') parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM') + parser.add_argument('--jacocout', help='specify the output directory for jacoco report') args = parser.parse_args(args) @@ -660,7 +673,7 @@ t = Task('BuildJava') build(['--no-native']) tasks.append(t.stop()) - + global _jacoco for vmbuild in ['fastdebug', 'product']: global _vmbuild _vmbuild = vmbuild @@ -674,19 +687,35 @@ vm(['-esa', '-version']) tasks.append(t.stop()) + if vmbuild == 'product' and args.jacocout is not None: + _jacoco = 'on' + t = Task('UnitTests:' + vmbuild) unittest([]) tasks.append(t.stop()) + if vmbuild == 'product' and args.jacocout is not None: + _jacoco = 'append' + t = Task('JavaTesterTests:' + vmbuild) jtt([]) tasks.append(t.stop()) + if vmbuild == 'product' and args.jacocout is not None: + _jacoco = 'off' + for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild): t = Task(str(test) + ':' + vmbuild) if not test.test('graal'): t.abort(test.group + ' ' + test.name + ' Failed') tasks.append(t.stop()) + + if args.jacocout is not None: + jacocoreport([args.jacocout]) + + t = Task('BootstrapWithDeoptALot') + vm(['-XX:+DeoptimizeALot', '-XX:+VerifyOops', '-version'], vmbuild='fastdebug') + tasks.append(t.stop()) t = Task('Checkstyle') if mx.checkstyle([]) != 0: @@ -727,7 +756,9 @@ def gv(args): """run the Graal Visualizer""" - mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'run']) + with open(join(_graal_home, '.graal_visualizer.log'), 'w') as fp: + mx.log('[Graal Visualizer output is in ' + fp.name + ']') + mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-l', fp.name, 'run']) def bench(args): """run benchmarks and parse their output for results @@ -852,6 +883,7 @@ 'clean': [clean, ''], 'copyrightcheck': [copyrightcheck, ''], 'hsdis': [hsdis, '[att]'], + 'intro': [intro, ''], 'dacapo': [dacapo, '[[n] benchmark] [VM options|@DaCapo options]'], 'scaladacapo': [scaladacapo, '[[n] benchmark] [VM options|@Scala DaCapo options]'], 'specjvm2008': [specjvm2008, '[VM options|@specjvm2008 options]'], diff -r b4f548d49f96 -r 90c150a0a22b mx/projects --- a/mx/projects Thu Mar 08 12:45:49 2012 +0100 +++ b/mx/projects Thu Mar 08 12:46:19 2012 +0100 @@ -1,32 +1,4 @@ -# Library specification format: -# -# library@@= -# -# Library properties (* = required): -# -# *path: the file system path for the library to appear on a class path -# urls: a comma seperated list of URLs from which the library can be downloaded -# optional: if "true" then this library will be omitted from a class path if it doesn't exist on the file system and no URLs are specified -# eclipse.container: the name of the Eclipse library container corresponding to the library -# -# Project specification format: -# -# project@@= -# -# The name of a project also denotes the directory it is in. -# -# Project properties: -# -# *sourceDirs: a comma separated list of source directoriy names (relative to the project directory) -# dependencies: a comma separated list of the libraries and project the project depends upon (transitive dependencies may be omitted) -# eclipse.output: the output directory name (relative to the project directory) -# checkstyle: the project whose Checkstyle configuration (i.e. /.checkstyle_checks.xml) is used -# -# The eclipse.* properties are only used when generating Eclipse project configuration files. -# -# Values can use environment variables with the syntax used in a Bash shell script. -# - +# The format of this file is described in the documentation for my.py. library@JDK_TOOLS@path=${JAVA_HOME}/lib/tools.jar library@JDK_TOOLS@optional=true @@ -55,91 +27,113 @@ project@com.oracle.max.graal.hotspot@sourceDirs=src project@com.oracle.max.graal.hotspot@dependencies=com.oracle.max.graal.snippets project@com.oracle.max.graal.hotspot@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.hotspot@javaCompliance=1.7 # graal.graph project@com.oracle.max.graal.graph@subDir=graal project@com.oracle.max.graal.graph@sourceDirs=src project@com.oracle.max.graal.graph@dependencies=com.oracle.max.graal.debug,JUNIT +project@com.oracle.max.graal.graph@javaCompliance=1.7 # graal.debug project@com.oracle.max.graal.debug@subDir=graal project@com.oracle.max.graal.debug@sourceDirs=src project@com.oracle.max.graal.debug@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.debug@javaCompliance=1.7 # graal.lir project@com.oracle.max.graal.lir@subDir=graal project@com.oracle.max.graal.lir@sourceDirs=src project@com.oracle.max.graal.lir@dependencies=com.oracle.max.asm,com.oracle.max.graal.nodes project@com.oracle.max.graal.lir@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.lir@javaCompliance=1.7 # graal.lir.amd64 project@com.oracle.max.graal.lir.amd64@subDir=graal project@com.oracle.max.graal.lir.amd64@sourceDirs=src project@com.oracle.max.graal.lir.amd64@dependencies=com.oracle.max.graal.lir project@com.oracle.max.graal.lir.amd64@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.lir.amd64@javaCompliance=1.7 # graal.alloc project@com.oracle.max.graal.alloc@subDir=graal project@com.oracle.max.graal.alloc@sourceDirs=src project@com.oracle.max.graal.alloc@dependencies=com.oracle.max.graal.lir project@com.oracle.max.graal.alloc@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.alloc@javaCompliance=1.7 # graal.snippets project@com.oracle.max.graal.snippets@subDir=graal project@com.oracle.max.graal.snippets@sourceDirs=src,test project@com.oracle.max.graal.snippets@dependencies=com.oracle.max.graal.printer project@com.oracle.max.graal.snippets@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.snippets@javaCompliance=1.7 # graal.nodes project@com.oracle.max.graal.nodes@subDir=graal project@com.oracle.max.graal.nodes@sourceDirs=src,test project@com.oracle.max.graal.nodes@dependencies=com.oracle.max.cri,com.oracle.max.graal.graph project@com.oracle.max.graal.nodes@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.nodes@javaCompliance=1.7 # graal.compiler project@com.oracle.max.graal.compiler@subDir=graal project@com.oracle.max.graal.compiler@sourceDirs=src project@com.oracle.max.graal.compiler@dependencies=com.oracle.max.graal.lir.amd64,com.oracle.max.graal.alloc project@com.oracle.max.graal.compiler@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.compiler@javaCompliance=1.7 # graal.java project@com.oracle.max.graal.java@subDir=graal project@com.oracle.max.graal.java@sourceDirs=src project@com.oracle.max.graal.java@dependencies=com.oracle.max.graal.compiler project@com.oracle.max.graal.java@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.java@javaCompliance=1.7 # graal.printer project@com.oracle.max.graal.printer@subDir=graal project@com.oracle.max.graal.printer@sourceDirs=src project@com.oracle.max.graal.printer@dependencies=com.oracle.max.graal.java project@com.oracle.max.graal.printer@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.printer@javaCompliance=1.7 # graal.test project@com.oracle.max.graal.tests@subDir=graal project@com.oracle.max.graal.tests@sourceDirs=src project@com.oracle.max.graal.tests@dependencies=com.oracle.max.graal.printer project@com.oracle.max.graal.tests@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.tests@javaCompliance=1.7 # graal.jtt project@com.oracle.max.graal.jtt@subDir=graal project@com.oracle.max.graal.jtt@sourceDirs=src project@com.oracle.max.graal.jtt@dependencies=JUNIT project@com.oracle.max.graal.jtt@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.jtt@javaCompliance=1.7 + +# graal.examples +project@com.oracle.max.graal.examples@subDir=graal +project@com.oracle.max.graal.examples@sourceDirs=src +project@com.oracle.max.graal.examples@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.graal.examples@javaCompliance=1.7 # max.asm project@com.oracle.max.asm@subDir=graal project@com.oracle.max.asm@sourceDirs=src project@com.oracle.max.asm@dependencies=com.oracle.max.criutils project@com.oracle.max.asm@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.asm@javaCompliance=1.7 # max.cri project@com.oracle.max.cri@subDir=graal project@com.oracle.max.cri@sourceDirs=src project@com.oracle.max.cri@dependencies= project@com.oracle.max.cri@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.cri@javaCompliance=1.7 # max.criutils project@com.oracle.max.criutils@subDir=graal project@com.oracle.max.criutils@sourceDirs=src project@com.oracle.max.criutils@dependencies=com.oracle.max.cri project@com.oracle.max.criutils@checkstyle=com.oracle.max.graal.graph +project@com.oracle.max.criutils@javaCompliance=1.7 diff -r b4f548d49f96 -r 90c150a0a22b mx/sanitycheck.py diff -r b4f548d49f96 -r 90c150a0a22b mxtool/mx.py --- a/mxtool/mx.py Thu Mar 08 12:45:49 2012 +0100 +++ b/mxtool/mx.py Thu Mar 08 12:46:19 2012 +0100 @@ -25,64 +25,104 @@ # # ---------------------------------------------------------------------------------------------------- # -# mx is a command line tool inspired by mvn (http://maven.apache.org/) -# and hg (http://mercurial.selenic.com/). It includes a mechanism for -# managing the dependencies between a set of projects (like Maven) -# as well as making it simple to run commands -# (like hg is the interface to the Mercurial commands). -# -# The organizing principle of mx is a project suite. A suite is a directory -# containing one or more projects. It's not coincidental that this closely -# matches the layout of one or more projects in a Mercurial repository. -# The configuration information for a suite lives in an 'mx' sub-directory -# at the top level of the suite. -# -# When launched, mx treats the current working directory as a suite. -# This is the primary suite. All other suites are called included suites. -# -# The configuration files (i.e. in the 'mx' sub-directory) of a suite are: -# -# projects - Defines the projects and libraries in the suite and the dependencies between them -# commands.py - Suite specific extensions to the commands available to mx. This is only processed -# for the primary suite. -# includes - Other suites to be loaded. This is recursive. -# env - A set of environment variable definitions. -# -# The includes and env files are typically not put under version control -# as they usually contain local file-system paths. -# -# The projects file is like the pom.xml file from Maven except that -# it is a properties file (not XML). Each non-comment line -# in the file specifies an attribute of a project or library. The main -# difference between a project and a library is that the former contains -# source code built by the mx tool where as the latter is an external -# dependency. The format of the projects file is -# -# Library specification format: -# -# library@@= -# -# Built-in library properties (* = required): -# -# *path: the file system path for the library to appear on a class path -# urls: a comma seperated list of URLs from which the library can be downloaded -# optional: if "true" then this library will be omitted from a class path if it doesn't exist on the file system and no URLs are specified -# -# Project specification format: -# -# project@@= -# -# The name of a project also denotes the directory it is in. -# -# Built-in project properties: -# -# *sourceDirs: a comma separated list of source directoriy names (relative to the project directory) -# dependencies: a comma separated list of the libraries and project the project depends upon (transitive dependencies may be omitted) -# checkstyle: the project whose Checkstyle configuration (i.e. /.checkstyle_checks.xml) is used -# -# Other properties can be specified for projects and libraries for use by extension commands. -# -# Values can use environment variables with Bash syntax (e.g. ${HOME}). + +r""" +mx is a command line tool inspired by mvn (http://maven.apache.org/) +and hg (http://mercurial.selenic.com/). It includes a mechanism for +managing the dependencies between a set of projects (like Maven) +as well as making it simple to run commands +(like hg is the interface to the Mercurial commands). + +The organizing principle of mx is a project suite. A suite is a directory +containing one or more projects. It's not coincidental that this closely +matches the layout of one or more projects in a Mercurial repository. +The configuration information for a suite lives in an 'mx' sub-directory +at the top level of the suite. + +When launched, mx treats the current working directory as a suite. +This is the primary suite. All other suites are called included suites. + +The configuration files (i.e. in the 'mx' sub-directory) of a suite are: + + projects + Defines the projects and libraries in the suite and the + dependencies between them. + + commands.py + Suite specific extensions to the commands available to mx. + This is only processed for the primary suite. + + includes + Other suites to be loaded. This is recursive. + + env + A set of environment variable definitions. These override any + existing environment variables. + +The includes and env files are typically not put under version control +as they usually contain local file-system paths. + +The projects file is like the pom.xml file from Maven except that +it is a properties file (not XML). Each non-comment line +in the file specifies an attribute of a project or library. The main +difference between a project and a library is that the former contains +source code built by the mx tool where as the latter is an external +dependency. The format of the projects file is + +Library specification format: + + library@@= + +Built-in library properties (* = required): + + *path + The file system path for the library to appear on a class path. + + urls + A comma separated list of URLs from which the library (jar) can + be downloaded and saved in the location specified by 'path'. + + optional + If "true" then this library will be omitted from a class path + if it doesn't exist on the file system and no URLs are specified. + +Project specification format: + + project@@= + +The name of a project also denotes the directory it is in. + +Built-in project properties (* = required): + + subDir + The sub-directory of the suite in which the project directory is + contained. If not specified, the project directory is directly + under the suite directory. + + *sourceDirs + A comma separated list of source directory names (relative to + the project directory). + + dependencies + A comma separated list of the libraries and project the project + depends upon (transitive dependencies should be omitted). + + checkstyle + The project whose Checkstyle configuration + (i.e. /.checkstyle_checks.xml) is used. + + native + "true" if the project is native. + + javaCompliance + The minimum JDK version (format: x.y) to which the project's + sources comply (required for non-native projects). + +Other properties can be specified for projects and libraries for use +by extension commands. + +Property values can use environment variables with Bash syntax (e.g. ${HOME}). +""" import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal import shutil, fnmatch, re, xml.dom.minidom @@ -107,31 +147,32 @@ def __init__(self, suite, name): self.name = name self.suite = suite - + def __str__(self): return self.name - + def __eq__(self, other): return self.name == other.name - + def __ne__(self, other): return self.name != other.name def __hash__(self): return hash(self.name) - + def isLibrary(self): return isinstance(self, Library) - + class Project(Dependency): - def __init__(self, suite, name, srcDirs, deps, dir): + def __init__(self, suite, name, srcDirs, deps, javaCompliance, dir): Dependency.__init__(self, suite, name) self.srcDirs = srcDirs self.deps = deps self.checkstyleProj = name + self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None self.native = False self.dir = dir - + def all_deps(self, deps, includeLibs, includeSelf=True): """ Add the transitive set of dependencies for this project, including @@ -152,7 +193,7 @@ if not self in deps and includeSelf: deps.append(self) return deps - + def _compute_max_dep_distances(self, name, distances, dist): currentDist = distances.get(name); if currentDist is None or currentDist < dist: @@ -161,7 +202,7 @@ if p is not None: for dep in p.deps: self._compute_max_dep_distances(dep, distances, dist + 1) - + def canonical_deps(self): """ Get the dependencies of this project that are not recursive (i.e. cannot be reached @@ -174,19 +215,19 @@ assert d > 0 or n == self.name if d == 1: result.add(n) - - + + if len(result) == len(self.deps) and frozenset(self.deps) == result: return self.deps return result; - + def source_dirs(self): """ Get the directories in which the sources of this project are found. """ return [join(self.dir, s) for s in self.srcDirs] - + def output_dir(self): """ Get the directory in which the class files of this project are found/placed. @@ -195,6 +236,14 @@ return None return join(self.dir, 'bin') + def jasmin_output_dir(self): + """ + Get the directory in which the Jasmin assembled class files of this project are found/placed. + """ + if self.native: + return None + return join(self.dir, 'jasmin_classes') + def append_to_classpath(self, cp, resolve): if not self.native: cp.append(self.output_dir()) @@ -205,7 +254,7 @@ self.path = path.replace('/', os.sep) self.urls = urls self.mustExist = mustExist - + def get_path(self, resolve): path = self.path if not isabs(path): @@ -214,14 +263,14 @@ assert not len(self.urls) == 0, 'cannot find required library ' + self.name + " " + path; print('Downloading ' + self.name + ' from ' + str(self.urls)) download(path, self.urls) - + return path - + def append_to_classpath(self, cp, resolve): path = self.get_path(resolve) if exists(path) or not resolve: cp.append(path) - + class Suite: def __init__(self, dir, primary): self.dir = dir @@ -237,7 +286,7 @@ def _load_projects(self, mxDir): libsMap = dict() - projsMap = dict() + projsMap = dict() projectsFile = join(mxDir, 'projects') if not exists(projectsFile): return @@ -246,9 +295,9 @@ line = line.strip() if len(line) != 0 and line[0] != '#': key, value = line.split('=', 1) - + parts = key.split('@') - + if len(parts) == 2: pass if len(parts) != 3: @@ -260,31 +309,34 @@ m = libsMap else: abort('Property name does not start with "project@" or "library@": ' + key) - + attrs = m.get(name) if attrs is None: attrs = dict() m[name] = attrs value = expandvars_in_property(value) attrs[attr] = value - + def pop_list(attrs, name): v = attrs.pop(name, None) if v is None or len(v.strip()) == 0: return [] return [n.strip() for n in v.split(',')] - + for name, attrs in projsMap.iteritems(): srcDirs = pop_list(attrs, 'sourceDirs') deps = pop_list(attrs, 'dependencies') + javaCompliance = attrs.pop('javaCompliance', None) subDir = attrs.pop('subDir', None); if subDir is None: dir = join(self.dir, name) else: dir = join(self.dir, subDir, name) - p = Project(self, name, srcDirs, deps, dir) + p = Project(self, name, srcDirs, deps, javaCompliance, dir) p.checkstyleProj = attrs.pop('checkstyle', name) p.native = attrs.pop('native', '') == 'true' + if not p.native and p.javaCompliance is None: + abort('javaCompliance property required for non-native project ' + name) p.__dict__.update(attrs) self.projects.append(p) @@ -295,15 +347,15 @@ l = Library(self, name, path, mustExist, urls) l.__dict__.update(attrs) self.libs.append(l) - + def _load_commands(self, mxDir): commands = join(mxDir, 'commands.py') if exists(commands): # temporarily extend the Python path sys.path.insert(0, mxDir) - + mod = __import__('commands') - + # revert the Python path del sys.path[0] @@ -311,17 +363,17 @@ abort(commands + ' must define an mx_init(env) function') if hasattr(mod, 'mx_post_parse_cmd_line'): self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line - + mod.mx_init() self.commands = mod - + def _load_includes(self, mxDir): includes = join(mxDir, 'includes') if exists(includes): with open(includes) as f: for line in f: self.includes.append(expandvars_in_property(line.strip())) - + def _load_env(self, mxDir): e = join(mxDir, 'env') if exists(e): @@ -331,7 +383,7 @@ if len(line) != 0 and line[0] != '#': key, value = line.split('=', 1) os.environ[key.strip()] = expandvars_in_property(value.strip()) - + def _post_init(self, opts): mxDir = join(self.dir, 'mx') self._load_includes(mxDir) @@ -348,7 +400,7 @@ if existing is not None: abort('cannot redefine library ' + l.name) _libs[l.name] = l - + def get_os(): """ Get a canonical form of sys.platform. @@ -371,7 +423,7 @@ if not _suites.has_key(dir): suite = Suite(dir, primary) _suites[dir] = suite - return suite + return suite def suites(): """ @@ -384,7 +436,7 @@ Get the list of all loaded projects. """ return _projects.values() - + def project(name, fatalIfMissing=True): """ Get the project for a given name. This will abort if the named project does @@ -421,7 +473,7 @@ path (e.g. downloading a missing library) if 'resolve' is true. """ if names is None: - return _as_classpath(sorted_deps(True), resolve) + return _as_classpath(sorted_deps(includeLibs=True), resolve) deps = [] if isinstance(names, types.StringTypes): project(names).all_deps(deps, True, includeSelf) @@ -429,15 +481,20 @@ for n in names: project(n).all_deps(deps, True, includeSelf) return _as_classpath(deps, resolve) - -def sorted_deps(includeLibs=False): + +def sorted_deps(projectNames=None, includeLibs=False): """ - Gets the loaded projects and libraries sorted such that dependencies + Gets projects and libraries sorted such that dependencies are before the projects that depend on them. Unless 'includeLibs' is true, libraries are omitted from the result. """ deps = [] - for p in _projects.itervalues(): + if projectNames is None: + projects = _projects.values() + else: + projects = [project(name) for name in projectNames] + + for p in projects: p.all_deps(deps, includeLibs) return deps @@ -446,14 +503,15 @@ # Override parent to append the list of available commands def format_help(self): return ArgumentParser.format_help(self) + _format_commands() - - + + def __init__(self): self.java_initialized = False ArgumentParser.__init__(self, prog='mx') - + self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') - self.add_argument('-d', action='store_true', dest='java_dbg', help='make Java processes wait on port 8000 for a debugger') + self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on for a debugger', metavar='') + self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='') self.add_argument('--cp-sfx', dest='cp_suffix', help='class path suffix', metavar='') self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@', default=DEFAULT_JAVA_ARGS) @@ -465,15 +523,15 @@ # Time outs are (currently) implemented with Unix specific functionality self.add_argument('--timeout', help='Timeout (in seconds) for command', type=int, default=0, metavar='') self.add_argument('--ptimeout', help='Timeout (in seconds) for subprocesses', type=int, default=0, metavar='') - + def _parse_cmd_line(self, args=None): if args is None: args = sys.argv[1:] self.add_argument('commandAndArgs', nargs=REMAINDER, metavar='command args...') - + opts = self.parse_args() - + # Give the timeout options a default value to avoid the need for hasattr() tests opts.__dict__.setdefault('timeout', 0) opts.__dict__.setdefault('ptimeout', 0) @@ -486,13 +544,13 @@ if opts.user_home is None or opts.user_home == '': abort('Could not find user home. Use --user-home option or ensure HOME environment variable is set.') - + os.environ['JAVA_HOME'] = opts.java_home os.environ['HOME'] = opts.user_home - + commandAndArgs = opts.__dict__.pop('commandAndArgs') return opts, commandAndArgs - + def _format_commands(): msg = '\navailable commands:\n\n' for cmd in sorted(commands.iterkeys()): @@ -531,7 +589,7 @@ if e.errno == errno.EINTR: continue raise - + def _returncode(status): if os.WIFSIGNALED(status): return -os.WTERMSIG(status) @@ -540,7 +598,7 @@ else: # Should never happen raise RuntimeError("Unknown child exit status!") - + end = time.time() + timeout delay = 0.0005 while True: @@ -576,19 +634,19 @@ Each line of the standard output and error streams of the subprocess are redirected to out and err if they are callable objects. """ - + assert isinstance(args, types.ListType), "'args' must be a list: " + str(args) for arg in args: assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg) - + if _opts.verbose: log(' '.join(args)) - + if timeout is None and _opts.ptimeout != 0: timeout = _opts.ptimeout global _currentSubprocess - + try: # On Unix, the new subprocess should be in a separate group so that a timeout alarm # can use os.killpg() to kill the whole subprocess group @@ -597,13 +655,13 @@ if get_os() == 'windows': creationflags = subprocess.CREATE_NEW_PROCESS_GROUP else: - preexec_fn = os.setsid - + preexec_fn = os.setsid + if not callable(out) and not callable(err) and timeout is None: # The preexec_fn=os.setsid p = subprocess.Popen(args, cwd=cwd, preexec_fn=preexec_fn, creationflags=creationflags) _currentSubprocess = (p, args) - retcode = waitOn(p) + retcode = waitOn(p) else: def redirect(stream, f): for line in iter(stream.readline, ''): @@ -641,12 +699,12 @@ if _opts.verbose: raise subprocess.CalledProcessError(retcode, ' '.join(args)) abort(retcode) - + return retcode def exe_suffix(name): """ - Gets the platform specific suffix for an executable + Gets the platform specific suffix for an executable """ if get_os() == 'windows': return name + '.exe' @@ -664,12 +722,30 @@ return name """ +A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string. +""" +class JavaCompliance: + def __init__(self, ver): + m = re.match('1\.(\d+).*', ver) + assert m is not None, 'not a recognized version string: ' + vstring + self.value = int(m.group(1)) + + def __str__ (self): + return '1.' + str(self.value) + + def __cmp__ (self, other): + if isinstance(other, types.StringType): + other = JavaCompliance(other) + + return cmp(self.value, other.value) + +""" A JavaConfig object encapsulates info on how Java commands are run. """ class JavaConfig: def __init__(self, opts): self.jdk = opts.java_home - self.debug = opts.java_dbg + self.debug_port = opts.java_dbg_port self.java = exe_suffix(join(self.jdk, 'bin', 'java')) self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) @@ -679,11 +755,11 @@ def delAtAndSplit(s): return shlex.split(s.lstrip('@')) - + self.java_args = delAtAndSplit(_opts.java_args) self.java_args_pfx = sum(map(delAtAndSplit, _opts.java_args_pfx), []) self.java_args_sfx = sum(map(delAtAndSplit, _opts.java_args_sfx), []) - + # Prepend the -d64 VM option only if the java command supports it try: output = subprocess.check_output([self.java, '-d64', '-version'], stderr=subprocess.STDOUT) @@ -694,17 +770,18 @@ except subprocess.CalledProcessError as e: print e.output abort(e.returncode) - + output = output.split() assert output[1] == 'version' self.version = output[2].strip('"') - - if self.debug: - self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000'] + self.javaCompliance = JavaCompliance(self.version) + + if self.debug_port is not None: + self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(self.debug_port)] def format_cmd(self, args): return [self.java] + self.java_args_pfx + self.java_args + self.java_args_sfx + args - + def check_get_env(key): """ Gets an environment variable, aborting with a useful message if it is not set. @@ -725,7 +802,7 @@ """ Write a message to the console. All script output goes through this method thus allowing a subclass - to redirect it. + to redirect it. """ if msg is None: print @@ -740,7 +817,7 @@ else: cp.append(part) return os.pathsep.join(cp) - + def expand_project_in_args(args): for i in range(len(args)): if args[i] == '-cp' or args[i] == '-classpath': @@ -765,7 +842,7 @@ abort('Property contains an undefined environment variable: ' + value) return result - + def abort(codeOrMessage): """ Aborts the program with a SystemExit exception. @@ -773,7 +850,7 @@ if it is None, the exit status is zero; if it has another type (such as a string), the object's value is printed and the exit status is one. """ - + #import traceback #traceback.print_stack() currentSubprocess = _currentSubprocess @@ -783,7 +860,7 @@ p.kill() else: _kill_process_group(p.pid) - + raise SystemExit(codeOrMessage) def download(path, urls, verbose=False): @@ -795,23 +872,23 @@ d = dirname(path) if d != '' and not exists(d): os.makedirs(d) - + # Try it with the Java tool first since it can show a progress counter myDir = dirname(__file__) - + javaSource = join(myDir, 'URLConnectionDownload.java') javaClass = join(myDir, 'URLConnectionDownload.class') if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource): subprocess.check_call([java().javac, '-d', myDir, javaSource]) if run([java().java, '-cp', myDir, 'URLConnectionDownload', path] + urls) == 0: return - + def url_open(url): userAgent = 'Mozilla/5.0 (compatible)' headers = { 'User-Agent' : userAgent } req = urllib2.Request(url, headers=headers) return urllib2.urlopen(req); - + for url in urls: try: if (verbose): @@ -824,7 +901,7 @@ with contextlib.closing(url_open(url)) as f: data = f.read() zipdata = StringIO.StringIO(f.read()) - + zf = zipfile.ZipFile(zipdata, 'r') data = zf.read(entry) with open(path, 'wb') as f: @@ -839,10 +916,10 @@ log('Error reading from ' + url + ': ' + str(e)) except zipfile.BadZipfile as e: log('Error in zip file downloaded from ' + url + ': ' + str(e)) - + abort('Could not download to ' + path + ' from any of the following URLs:\n\n ' + '\n '.join(urls) + '\n\nPlease use a web browser to do the download manually') - + def update_file(path, content): """ Updates a file with some given content if the content differs from what's in @@ -854,44 +931,47 @@ if existed: with open(path, 'rb') as f: old = f.read() - + if old == content: return False - + with open(path, 'wb') as f: f.write(content) - + log(('modified ' if existed else 'created ') + path) return True; except IOError as e: abort('Error while writing to ' + path + ': ' + str(e)); # Builtin commands - + def build(args, parser=None): """compile the Java and C sources, linking the latter Compile all the Java source code using the appropriate compilers and linkers for the various source code types.""" - + suppliedParser = parser is not None if not suppliedParser: parser = ArgumentParser(prog='mx build') - + + javaCompliance = java().javaCompliance + parser = parser if parser is not None else ArgumentParser(prog='mx build') parser.add_argument('-f', action='store_true', dest='force', help='force compilation even if class files are up to date') parser.add_argument('-c', action='store_true', dest='clean', help='removes existing build output') - parser.add_argument('--source', dest='compliance', help='Java compliance level', default='1.6') + parser.add_argument('--source', dest='compliance', help='Java compliance level', default=str(javaCompliance)) parser.add_argument('--Wapi', action='store_true', dest='warnAPI', help='show warnings about using internal APIs') + parser.add_argument('--projects', action='store', help='comma separated projects to build (omit to build all projects)') parser.add_argument('--no-java', action='store_false', dest='java', help='do not build Java projects') parser.add_argument('--no-native', action='store_false', dest='native', help='do not build native projects') parser.add_argument('--jdt', help='Eclipse installation or path to ecj.jar for using the Eclipse batch compiler instead of javac', metavar='') - + if suppliedParser: parser.add_argument('remainder', nargs=REMAINDER, metavar='...') args = parser.parse_args(args) - + jdtJar = None if args.jdt is not None: if args.jdt.endswith('.jar'): @@ -903,15 +983,19 @@ jdtJar = join(plugins, sorted(choices, reverse=True)[0]) built = set() - for p in sorted_deps(): - + + projects = None + if args.projects is not None: + projects = args.projects.split(',') + + for p in sorted_deps(projects): if p.native: if args.native: log('Calling GNU make {0}...'.format(p.dir)) - + if args.clean: run([gmake_cmd(), 'clean'], cwd=p.dir) - + run([gmake_cmd()], cwd=p.dir) built.add(p.name) continue @@ -919,7 +1003,12 @@ if not args.java: continue - + # skip building this Java project if its Java compliance level is "higher" than the configured JDK + if javaCompliance < p.javaCompliance: + log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) + continue + + outputDir = p.output_dir() if exists(outputDir): if args.clean: @@ -936,31 +1025,63 @@ for dep in p.all_deps([], False): if dep.name in built: mustBuild = True - + + jasminAvailable = None javafilelist = [] for sourceDir in sourceDirs: for root, _, files in os.walk(sourceDir): javafiles = [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] javafilelist += javafiles - - # Copy all non Java resources + + # Copy all non Java resources or assemble Jasmin files nonjavafilelist = [join(root, name) for name in files if not name.endswith('.java')] for src in nonjavafilelist: - dst = join(outputDir, src[len(sourceDir) + 1:]) - if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) != os.path.getmtime(src)): - shutil.copyfile(src, dst) - + if src.endswith('.jasm'): + className = None + with open(src) as f: + for line in f: + if line.startswith('.class '): + className = line.split()[-1] + break + + if className is not None: + jasminOutputDir = p.jasmin_output_dir() + classFile = join(jasminOutputDir, className.replace('/', os.sep) + '.class') + if exists(dirname(classFile)) and (not exists(classFile) or os.path.getmtime(classFile) < os.path.getmtime(src)): + if jasminAvailable is None: + try: + with open(os.devnull) as devnull: + subprocess.call('jasmin', stdout=devnull, stderr=subprocess.STDOUT) + jasminAvailable = True + except OSError as e: + jasminAvailable = False + + if jasminAvailable: + log('Assembling Jasmin file ' + src) + run(['jasmin', '-d', jasminOutputDir, src]) + else: + log('The jasmin executable could not be found - skipping ' + src) + with file(classFile, 'a'): + os.utime(classFile, None) + + else: + log('could not file .class directive in Jasmin source: ' + src) + else: + dst = join(outputDir, src[len(sourceDir) + 1:]) + if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) != os.path.getmtime(src)): + shutil.copyfile(src, dst) + if not mustBuild: for javafile in javafiles: classfile = outputDir + javafile[len(sourceDir):-len('java')] + 'class' if not exists(classfile) or os.path.getmtime(javafile) > os.path.getmtime(classfile): mustBuild = True break - + if not mustBuild: log('[all class files for {0} are up to date - skipping]'.format(p.name)) continue - + if len(javafilelist) == 0: log('[no Java sources for {0} - skipping]'.format(p.name)) continue @@ -971,7 +1092,7 @@ argfile = open(argfileName, 'wb') argfile.write('\n'.join(javafilelist)) argfile.close() - + try: if jdtJar is None: log('Compiling Java sources for {0} with javac...'.format(p.name)) @@ -981,11 +1102,11 @@ """ Class to errFilt the 'is Sun proprietary API and may be removed in a future release' warning when compiling the VM classes. - + """ def __init__(self): self.c = 0 - + def eat(self, line): if 'proprietary API' in line: self.c = 2 @@ -994,7 +1115,7 @@ else: log(line.rstrip()) errFilt=Filter().eat - + run([java().javac, '-g', '-J-Xmx1g', '-source', args.compliance, '-classpath', cp, '-d', outputDir, '@' + argfile.name], err=errFilt) else: log('Compiling Java sources for {0} with JDT...'.format(p.name)) @@ -1009,7 +1130,7 @@ '-d', outputDir, '@' + argfile.name]) finally: os.remove(argfileName) - + if suppliedParser: return args return None @@ -1018,7 +1139,7 @@ """process all project files to canonicalize the dependencies The exit code of this command reflects how many files were updated.""" - + changedFiles = 0 for s in suites(): projectsFile = join(s.dir, 'mx', 'projects') @@ -1039,7 +1160,7 @@ if update_file(projectsFile, content): changedFiles += 1 return changedFiles; - + def checkstyle(args): """run Checkstyle on the Java sources @@ -1047,16 +1168,16 @@ produced by Checkstyle result in a non-zero exit code. If no projects are given, then all Java projects are checked.""" - + for p in sorted_deps(): if p.native: continue sourceDirs = p.source_dirs() dotCheckstyle = join(p.dir, '.checkstyle') - + if not exists(dotCheckstyle): continue - + for sourceDir in sourceDirs: javafilelist = [] for root, _, files in os.walk(sourceDir): @@ -1075,16 +1196,16 @@ break else: mustCheck = True - + if not mustCheck: log('[all Java sources in {0} already checked - skipping]'.format(sourceDir)) continue - if exists(timestampFile): + if exists(timestampFile): os.utime(timestampFile, None) else: file(timestampFile, 'a') - + dotCheckstyleXML = xml.dom.minidom.parse(dotCheckstyle) localCheckConfig = dotCheckstyleXML.getElementsByTagName('local-check-config')[0] configLocation = localCheckConfig.getAttribute('location') @@ -1102,9 +1223,9 @@ else: log('[unknown Checkstyle configuration type "' + configType + '" in {0} - skipping]'.format(sourceDir)) continue - + exclude = join(p.dir, '.checkstyle.exclude') - + if exists(exclude): with open(exclude) as f: # Convert patterns to OS separators @@ -1112,15 +1233,16 @@ def match(name): for p in patterns: if p in name: - log('excluding: ' + name) + if _opts.verbose: + log('excluding: ' + name) return True return False - + javafilelist = [name for name in javafilelist if not match(name)] - + auditfileName = join(p.dir, 'checkstyleOutput.txt') log('Running Checkstyle on {0} using {1}...'.format(sourceDir, config)) - + try: # Checkstyle is unable to read the filenames to process from a file, and the @@ -1137,7 +1259,7 @@ i += 1 else: break - + batch = javafilelist[:i] javafilelist = javafilelist[i:] try: @@ -1162,13 +1284,13 @@ """ suppliedParser = parser is not None - + parser = parser if suppliedParser else ArgumentParser(prog='mx build'); parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects') parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects') args = parser.parse_args(args) - + for p in projects(): if p.native: if args.native: @@ -1179,10 +1301,14 @@ if outputDir != '' and exists(outputDir): log('Removing {0}...'.format(outputDir)) shutil.rmtree(outputDir) - + if suppliedParser: return args - + +def about(args): + """show the 'man page' for mx""" + print __doc__ + def help_(args): """show help for a given command @@ -1192,11 +1318,11 @@ if len(args) == 0: _argParser.print_help() return - + name = args[0] if not commands.has_key(name): _argParser.error('unknown command: ' + name) - + value = commands[name] (func, usage) = value[:2] doc = func.__doc__ @@ -1213,7 +1339,7 @@ def projectgraph(args, suite=None): """create dot graph for project structure ("mx projectgraph | dot -Tpdf -oprojects.pdf")""" - + print 'digraph projects {' print 'rankdir=BT;' print 'node [shape=rect];' @@ -1227,19 +1353,28 @@ if suite is None: suite = _mainSuite - + def println(out, obj): out.write(str(obj) + '\n') - + for p in projects(): - if p.native: - continue - if not exists(p.dir): os.makedirs(p.dir) + if p.native: + eclipseNativeSettingsDir = join(suite.dir, 'mx', 'eclipse-native-settings') + if exists(eclipseNativeSettingsDir): + for name in os.listdir(eclipseNativeSettingsDir): + path = join(eclipseNativeSettingsDir, name) + if isfile(path): + with open(join(eclipseNativeSettingsDir, name)) as f: + content = f.read() + content = content.replace('${javaHome}', java().jdk) + update_file(join(p.dir, name), content) + continue + out = StringIO.StringIO() - + println(out, '') println(out, '') for src in p.srcDirs: @@ -1247,14 +1382,14 @@ if not exists(srcDir): os.mkdir(srcDir) println(out, '\t') - + # Every Java program depends on the JRE println(out, '\t') - + for dep in p.all_deps([], True): if dep == p: continue; - + if dep.isLibrary(): if hasattr(dep, 'eclipse.container'): println(out, '\t') @@ -1267,10 +1402,11 @@ if isabs(path): println(out, '\t') else: - println(out, '\t') + projRelPath = os.path.relpath(join(suite.dir, path), p.dir) + println(out, '\t') else: println(out, '\t') - + println(out, '\t') println(out, '') update_file(join(p.dir, '.classpath'), out.getvalue()) @@ -1279,7 +1415,7 @@ csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml') if exists(csConfig): out = StringIO.StringIO() - + dotCheckstyle = join(p.dir, ".checkstyle") checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml' println(out, '') @@ -1305,14 +1441,14 @@ assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir println(out, '\t\t') println(out, '\t') - + println(out, '') update_file(dotCheckstyle, out.getvalue()) out.close() - + out = StringIO.StringIO() - + println(out, '') println(out, '') println(out, '\t' + p.name + '') @@ -1353,6 +1489,7 @@ if isfile(path): with open(join(eclipseSettingsDir, name)) as f: content = f.read() + content = content.replace('${javaCompliance}', str(p.javaCompliance)) update_file(join(settingsDir, name), content) def netbeansinit(args, suite=None): @@ -1363,17 +1500,17 @@ def println(out, obj): out.write(str(obj) + '\n') - + updated = False for p in projects(): if p.native: continue - + if not exists(join(p.dir, 'nbproject')): os.makedirs(join(p.dir, 'nbproject')) out = StringIO.StringIO() - + println(out, '') println(out, '') println(out, '\tBuilds, tests, and runs the project ' + p.name + '.') @@ -1381,7 +1518,7 @@ println(out, '') updated = update_file(join(p.dir, 'build.xml'), out.getvalue()) or updated out.close() - + out = StringIO.StringIO() println(out, '') println(out, '') @@ -1397,18 +1534,18 @@ println(out, ' ') println(out, ' ') println(out, ' ') - + firstDep = True for dep in p.all_deps([], True): if dep == p: continue; - + if not dep.isLibrary(): n = dep.name.replace('.', '_') if firstDep: println(out, ' ') firstDep = False - + println(out, ' ') println(out, ' ' + n + '') println(out, ' jar') @@ -1417,19 +1554,19 @@ println(out, ' clean') println(out, ' jar') println(out, ' ') - + if not firstDep: println(out, ' ') - + println(out, ' ') println(out, '') updated = update_file(join(p.dir, 'nbproject', 'project.xml'), out.getvalue()) or updated out.close() - + out = StringIO.StringIO() - + jdkPlatform = 'JDK_' + java().version - + content = """ annotation.processing.enabled=false annotation.processing.enabled.in.editor=false @@ -1517,12 +1654,12 @@ mainSrc = False else: println(out, 'src.' + src + '.dir=${' + ref + '}') - - javacClasspath = [] + + javacClasspath = [] for dep in p.all_deps([], True): if dep == p: continue; - + if dep.isLibrary(): if not dep.mustExist: continue @@ -1531,22 +1668,22 @@ path = path.replace('\\', '\\\\') ref = 'file.reference.' + dep.name + '-bin' println(out, ref + '=' + path) - + else: n = dep.name.replace('.', '_') relDepPath = os.path.relpath(dep.dir, p.dir).replace(os.sep, '/') ref = 'reference.' + n + '.jar' println(out, 'project.' + n + '=' + relDepPath) println(out, ref + '=${project.' + n + '}/dist/' + dep.name + '.jar') - + javacClasspath.append('${' + ref + '}') - + println(out, 'javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath)) - + updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated out.close() - + if updated: log('If using NetBeans:') log(' 1. Ensure that a platform named "JDK ' + java().version + '" is defined (Tools -> Java Platforms)') @@ -1554,21 +1691,21 @@ def ideclean(args, suite=None): """remove all Eclipse and NetBeans project configurations""" - + def rm(path): if exists(path): os.remove(path) - + for p in projects(): if p.native: continue - + shutil.rmtree(join(p.dir, '.settings'), ignore_errors=True) shutil.rmtree(join(p.dir, 'nbproject'), ignore_errors=True) rm(join(p.dir, '.classpath')) rm(join(p.dir, '.project')) rm(join(p.dir, 'build.xml')) - + def ideinit(args, suite=None): """(re)generate Eclipse and NetBeans project configurations""" eclipseinit(args, suite) @@ -1580,7 +1717,7 @@ Run the JDK javap class file disassembler with the following prepended options: -private -verbose -classpath """ - + javap = java().javap if not exists(javap): abort('The javap executable does not exists: ' + javap) @@ -1602,13 +1739,14 @@ """ assert _argParser is not None _argParser.add_argument(*args, **kwargs) - + # Table of commands in alphabetical order. # Keys are command names, value are lists: [, , ...] # If any of the format args are instances of Callable, then they are called with an 'env' are before being -# used in the call to str.format(). +# used in the call to str.format(). # Extensions should update this table directly commands = { + 'about': [about, ''], 'build': [build, '[options]'], 'checkstyle': [checkstyle, ''], 'canonicalizeprojects': [canonicalizeprojects, ''], @@ -1630,26 +1768,26 @@ if exists(cwdMxDir) and isdir(cwdMxDir): global _mainSuite _mainSuite = _loadSuite(os.getcwd(), True) - + opts, commandAndArgs = _argParser._parse_cmd_line() - + global _opts, _java _opts = opts _java = JavaConfig(opts) - + for s in suites(): s._post_init(opts) - + if len(commandAndArgs) == 0: _argParser.print_help() return - + command = commandAndArgs[0] command_args = commandAndArgs[1:] - + if not commands.has_key(command): abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(command, _format_commands())) - + c, _ = commands[command][:2] def term_handler(signum, frame): abort(1) diff -r b4f548d49f96 -r 90c150a0a22b src/cpu/x86/vm/c1_globals_x86.hpp --- a/src/cpu/x86/vm/c1_globals_x86.hpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/cpu/x86/vm/c1_globals_x86.hpp Thu Mar 08 12:46:19 2012 +0100 @@ -37,27 +37,41 @@ define_pd_global(bool, ResizeTLAB, true ); define_pd_global(bool, InlineIntrinsics, true ); define_pd_global(bool, PreferInterpreterNativeStubs, false); -define_pd_global(bool, ProfileTraps, true ); // changed for GRAAL -define_pd_global(bool, UseOnStackReplacement, true ); define_pd_global(bool, TieredCompilation, false); -define_pd_global(intx, CompileThreshold, 4500 ); // changed for GRAAL define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 933 ); define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(intx, NewSizeThreadIncrease, 4*K ); -define_pd_global(intx, InitialCodeCacheSize, 4*M); // changed for GRAAL -define_pd_global(intx, ReservedCodeCacheSize, 48*M ); // changed for GRAAL -define_pd_global(bool, ProfileInterpreter, true ); // changed for GRAAL -define_pd_global(intx, CodeCacheExpansionSize, 64*K ); // changed for GRAAL -define_pd_global(uintx,CodeCacheMinBlockLength, 4); // changed for GRAAL define_pd_global(uintx,PermSize, 12*M ); define_pd_global(uintx,MaxPermSize, 64*M ); define_pd_global(bool, NeverActAsServerClassMachine, true ); define_pd_global(uint64_t,MaxRAM, 1ULL*G); define_pd_global(bool, CICompileOSR, true ); -define_pd_global(intx, TypeProfileWidth, 8 ); // changed for GRAAL + +#ifdef GRAAL +define_pd_global(bool, ProfileTraps, true ); +define_pd_global(bool, UseOnStackReplacement, false); +define_pd_global(intx, CompileThreshold, 4500 ); +define_pd_global(intx, InitialCodeCacheSize, 4*M ); +define_pd_global(intx, ReservedCodeCacheSize, 48*M ); +define_pd_global(bool, ProfileInterpreter, true ); +define_pd_global(intx, CodeCacheExpansionSize, 64*K ); +define_pd_global(uintx,CodeCacheMinBlockLength, 4); +define_pd_global(intx, TypeProfileWidth, 8); +#else +define_pd_global(bool, ProfileTraps, false); +define_pd_global(bool, UseOnStackReplacement, true ); +define_pd_global(intx, CompileThreshold, 1500 ); +define_pd_global(intx, InitialCodeCacheSize, 160*K); +define_pd_global(intx, ReservedCodeCacheSize, 32*M ); +define_pd_global(bool, ProfileInterpreter, false); +define_pd_global(intx, CodeCacheExpansionSize, 32*K ); +define_pd_global(uintx,CodeCacheMinBlockLength, 1); +define_pd_global(intx, TypeProfileWidth, 0); +#endif // GRAAL #endif // !TIERED + define_pd_global(bool, RoundFPResults, true ); define_pd_global(bool, LIRFillDelaySlots, false); diff -r b4f548d49f96 -r 90c150a0a22b src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Mar 08 12:46:19 2012 +0100 @@ -346,7 +346,7 @@ // Test to see if we should create a method data oop __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit)); __ jcc(Assembler::less, *profile_method_continue); - + // if no method data exists, go to profile_method __ test_method_data_pointer(rax, *profile_method); } diff -r b4f548d49f96 -r 90c150a0a22b src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/share/vm/code/nmethod.cpp Thu Mar 08 12:46:19 2012 +0100 @@ -1178,7 +1178,9 @@ } void nmethod::inc_decompile_count() { +#ifndef GRAAL if (!is_compiled_by_c2()) return; +#endif // Could be gated by ProfileTraps, but do not bother... methodOop m = method(); if (m == NULL) return; diff -r b4f548d49f96 -r 90c150a0a22b src/share/vm/oops/methodDataOop.cpp --- a/src/share/vm/oops/methodDataOop.cpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/share/vm/oops/methodDataOop.cpp Thu Mar 08 12:46:19 2012 +0100 @@ -861,6 +861,19 @@ return CompilationPolicy::policy()->is_mature(_method); } +void methodDataOopDesc::inc_decompile_count() { + _nof_decompiles += 1; + if (decompile_count() > (uint)PerMethodRecompilationCutoff) { +#ifdef GRAAL + // TODO (ch) enable this in the fastdebug build only once we are more stable + ResourceMark m; + tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string()); + //ShouldNotReachHere(); +#endif + method()->set_not_compilable(CompLevel_full_optimization); + } +} + // Translate a bci to its corresponding data index (di). address methodDataOopDesc::bci_to_dp(int bci) { ResourceMark rm; diff -r b4f548d49f96 -r 90c150a0a22b src/share/vm/oops/methodDataOop.hpp --- a/src/share/vm/oops/methodDataOop.hpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/share/vm/oops/methodDataOop.hpp Thu Mar 08 12:46:19 2012 +0100 @@ -1507,12 +1507,7 @@ uint decompile_count() const { return _nof_decompiles; } - void inc_decompile_count() { - _nof_decompiles += 1; - if (decompile_count() > (uint)PerMethodRecompilationCutoff) { - method()->set_not_compilable(CompLevel_full_optimization); - } - } + void inc_decompile_count(); // Support for code generation static ByteSize data_offset() { diff -r b4f548d49f96 -r 90c150a0a22b src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Mar 08 12:45:49 2012 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Thu Mar 08 12:46:19 2012 +0100 @@ -164,7 +164,7 @@ // that can confuse an asynchronous stack walker. This counter is // decremented at the end of unpack_frames(). if (TraceDeoptimization) { - tty->print("Deoptimization "); + tty->print_cr("Deoptimizing thread " INTPTR_FORMAT, thread); } thread->inc_in_deopt_handler();