changeset 14627:46c020971d9c

Merge.
author Christian Humer <christian.humer@gmail.com>
date Thu, 20 Mar 2014 00:16:39 +0100
parents 4f8268dee8aa (current diff) 3ab42370f636 (diff)
children a08b8694f556
files
diffstat 17 files changed, 488 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/AllocSpy.java	Thu Mar 20 00:16:39 2014 +0100
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2011, 2014, 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.test;
+
+import static java.lang.Boolean.*;
+import static java.lang.Integer.*;
+import static java.lang.System.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.google.monitoring.runtime.instrumentation.*;
+
+/**
+ * Tool for analyzing allocations within a scope using the <a
+ * href="https://code.google.com/p/java-allocation-instrumenter/">Java Allocation Instrumenter</a>.
+ * Allocation records are aggregated per stack trace at an allocation site. The size of the stack
+ * trace is governed by the value of the "AllocSpy.ContextSize" system property (default is 5).
+ * <p>
+ * Using this facility requires using -javaagent on the command line. For example:
+ * 
+ * <pre>
+ * mx --vm server unittest -javaagent:lib/java-allocation-instrumenter.jar -dsa -DAllocSpy.ContextSize=6 BC_iadd2
+ * </pre>
+ * 
+ * @see #SampleBytes
+ * @see #SampleInstances
+ * @see #HistogramLimit
+ * @see #NameSize
+ * @see #BarSize
+ * @see #NumberSize
+ */
+final class AllocSpy implements AutoCloseable {
+
+    static ThreadLocal<AllocSpy> current = new ThreadLocal<>();
+
+    private static final boolean ENABLED;
+    static {
+        boolean enabled = false;
+        try {
+            Field field = AllocationRecorder.class.getDeclaredField("instrumentation");
+            field.setAccessible(true);
+            enabled = field.get(null) != null;
+        } catch (Exception e) {
+        }
+        ENABLED = enabled;
+        if (ENABLED) {
+            AllocationRecorder.addSampler(new GraalContextSampler());
+        }
+    }
+
+    static String prop(String sfx) {
+        return AllocSpy.class.getSimpleName() + "." + sfx;
+    }
+
+    /**
+     * Determines if bytes per allocation site are recorded.
+     */
+    private static final boolean SampleBytes = parseBoolean(getProperty(prop("SampleBytes"), "true"));
+
+    /**
+     * Determines if allocations per allocation site are recorded.
+     */
+    private static final boolean SampleInstances = parseBoolean(getProperty(prop("SampleInstances"), "true"));
+
+    /**
+     * The size of context to record for each allocation site in terms of Graal frames.
+     */
+    private static final int ContextSize = getInteger(prop("ContextSize"), 5);
+
+    /**
+     * Only the {@code HistogramLimit} most frequent values are printed.
+     */
+    private static final int HistogramLimit = getInteger(prop("HistogramLimit"), 40);
+
+    /**
+     * The width of the allocation context column.
+     */
+    private static final int NameSize = getInteger(prop("NameSize"), 50);
+
+    /**
+     * The width of the histogram bar column.
+     */
+    private static final int BarSize = getInteger(prop("BarSize"), 100);
+
+    /**
+     * The width of the frequency column.
+     */
+    private static final int NumberSize = getInteger(prop("NumberSize"), 10);
+
+    final Object name;
+    final AllocSpy parent;
+    final Map<String, CountedValue> bytesPerGraalContext = new HashMap<>();
+    final Map<String, CountedValue> instancesPerGraalContext = new HashMap<>();
+
+    public static AllocSpy open(Object name) {
+        if (ENABLED) {
+            return new AllocSpy(name);
+        }
+        return null;
+    }
+
+    private AllocSpy(Object name) {
+        this.name = name;
+        parent = current.get();
+        current.set(this);
+    }
+
+    public void close() {
+        current.set(parent);
+        PrintStream ps = System.out;
+        ps.println("\n\nAllocation histograms for " + name);
+        if (SampleBytes) {
+            print(ps, bytesPerGraalContext, "BytesPerGraalContext", HistogramLimit, NameSize + 60, BarSize);
+        }
+        if (SampleInstances) {
+            print(ps, instancesPerGraalContext, "InstancesPerGraalContext", HistogramLimit, NameSize + 60, BarSize);
+        }
+    }
+
+    private static void printLine(PrintStream printStream, char c, int lineSize) {
+        char[] charArr = new char[lineSize];
+        Arrays.fill(charArr, c);
+        printStream.printf("%s%n", new String(charArr));
+    }
+
+    private static void print(PrintStream ps, Map<String, CountedValue> map, String name, int limit, int nameSize, int barSize) {
+        if (map.isEmpty()) {
+            return;
+        }
+
+        List<CountedValue> list = new ArrayList<>(map.values());
+        Collections.sort(list);
+
+        // Sum up the total number of elements.
+        int total = 0;
+        for (CountedValue cv : list) {
+            total += cv.getCount();
+        }
+
+        // Print header.
+        ps.printf("%s has %d unique elements and %d total elements:%n", name, list.size(), total);
+
+        int max = list.get(0).getCount();
+        final int lineSize = nameSize + NumberSize + barSize + 10;
+        printLine(ps, '-', lineSize);
+        String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n";
+        for (int i = 0; i < list.size() && i < limit; ++i) {
+            CountedValue cv = list.get(i);
+            int value = cv.getCount();
+            char[] bar = new char[(int) (((double) value / (double) max) * barSize)];
+            Arrays.fill(bar, '=');
+            String[] lines = String.valueOf(cv.getValue()).split("\\n");
+
+            String objectString = lines[0];
+            if (objectString.length() > nameSize) {
+                objectString = objectString.substring(0, nameSize - 3) + "...";
+            }
+            ps.printf(formatString, objectString, value, new String(bar));
+            for (int j = 1; j < lines.length; j++) {
+                String line = lines[j];
+                if (line.length() > nameSize) {
+                    line = line.substring(0, nameSize - 3) + "...";
+                }
+                ps.printf("|   %-" + (nameSize - 2) + "s | %-" + NumberSize + "s | %-" + barSize + "s |%n", line, " ", " ");
+
+            }
+        }
+        printLine(ps, '-', lineSize);
+    }
+
+    CountedValue bytesPerGraalContext(String context) {
+        return getCounter(context, bytesPerGraalContext);
+    }
+
+    CountedValue instancesPerGraalContext(String context) {
+        return getCounter(context, instancesPerGraalContext);
+    }
+
+    protected static CountedValue getCounter(String desc, Map<String, CountedValue> map) {
+        CountedValue count = map.get(desc);
+        if (count == null) {
+            count = new CountedValue(0, desc);
+            map.put(desc, count);
+        }
+        return count;
+    }
+
+    private static final String[] Excluded = {AllocSpy.class.getName(), AllocationRecorder.class.getName()};
+
+    private static boolean excludeFrame(String className) {
+        for (String e : Excluded) {
+            if (className.startsWith(e)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static class GraalContextSampler implements Sampler {
+
+        public void sampleAllocation(int count, String desc, Object newObj, long size) {
+            AllocSpy scope = current.get();
+            if (scope != null) {
+                StringBuilder sb = new StringBuilder(200);
+                Throwable t = new Throwable();
+                int remainingGraalFrames = ContextSize;
+                for (StackTraceElement e : t.getStackTrace()) {
+                    if (remainingGraalFrames < 0) {
+                        break;
+                    }
+                    String className = e.getClassName();
+                    boolean isGraalFrame = className.contains(".graal.");
+                    if (sb.length() != 0) {
+                        append(sb.append('\n'), e);
+                    } else {
+                        if (!excludeFrame(className)) {
+                            sb.append("type=").append(desc);
+                            if (count != 1) {
+                                sb.append("[]");
+                            }
+                            append(sb.append('\n'), e);
+                        }
+                    }
+                    if (isGraalFrame) {
+                        remainingGraalFrames--;
+                    }
+                }
+                String context = sb.toString();
+                if (SampleBytes) {
+                    scope.bytesPerGraalContext(context).add((int) size);
+                }
+                if (SampleInstances) {
+                    scope.instancesPerGraalContext(context).inc();
+                }
+            }
+        }
+
+        protected StringBuilder append(StringBuilder sb, StackTraceElement e) {
+            String className = e.getClassName();
+            int period = className.lastIndexOf('.');
+            if (period != -1) {
+                sb.append(className, period + 1, className.length());
+            } else {
+                sb.append(className);
+            }
+            sb.append('.').append(e.getMethodName());
+            if (e.isNativeMethod()) {
+                sb.append("(Native Method)");
+            } else if (e.getFileName() != null && e.getLineNumber() >= 0) {
+                sb.append('(').append(e.getFileName()).append(':').append(e.getLineNumber()).append(")");
+            } else {
+                sb.append("(Unknown Source)");
+            }
+            return sb;
+        }
+    }
+
+    /**
+     * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places
+     * values with higher frequencies first.
+     */
+    static class CountedValue implements Comparable<CountedValue> {
+
+        private int count;
+        private final Object value;
+
+        public CountedValue(int count, Object value) {
+            this.count = count;
+            this.value = value;
+        }
+
+        public int compareTo(CountedValue o) {
+            if (count < o.count) {
+                return 1;
+            } else if (count > o.count) {
+                return -1;
+            }
+            return 0;
+        }
+
+        @Override
+        public String toString() {
+            return count + " -> " + value;
+        }
+
+        public void inc() {
+            count++;
+        }
+
+        public void add(int n) {
+            count += n;
+        }
+
+        public int getCount() {
+            return count;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Mar 20 00:16:39 2014 +0100
@@ -130,7 +130,7 @@
     @Before
     public void beforeTest() {
         assert debugScope == null;
-        debugScope = Debug.scope(getClass().getSimpleName());
+        debugScope = Debug.scope(getClass());
     }
 
     @After
@@ -498,7 +498,7 @@
     }
 
     private CompilationResult compileBaseline(ResolvedJavaMethod javaMethod) {
-        try (Scope bds = Debug.scope("compileBaseline")) {
+        try (Scope bds = Debug.scope("CompileBaseline")) {
             BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess());
             baselineCompiler.generate(javaMethod, -1);
             return null;
@@ -630,7 +630,7 @@
         final int id = compilationId.incrementAndGet();
 
         InstalledCode installedCode = null;
-        try (Scope ds = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
+        try (AllocSpy spy = AllocSpy.open(method); Scope ds = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
             final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
             if (printCompilation) {
                 TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature()));
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Thu Mar 20 00:16:39 2014 +0100
@@ -149,7 +149,7 @@
     protected void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) {
         ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet));
         graph = new StructuredGraph(method);
-        try (Scope s = Debug.scope(getClass().getSimpleName(), graph, method, getCodeCache())) {
+        try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) {
             new GraphBuilderPhase.Instance(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
             Assumptions assumptions = new Assumptions(false);
             context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Thu Mar 20 00:16:39 2014 +0100
@@ -130,7 +130,7 @@
 
     /**
      * Gets a string composed of the names in the current nesting of debug
-     * {@linkplain #scope(String, Object...) scopes} separated by {@code '.'}.
+     * {@linkplain #scope(Object) scopes} separated by {@code '.'}.
      */
     public static String currentScope() {
         if (ENABLED) {
@@ -141,7 +141,7 @@
     }
 
     /**
-     * Represents a debug scope entered by {@link Debug#scope(String, Object...)} or
+     * Represents a debug scope entered by {@link Debug#scope(Object)} or
      * {@link Debug#sandbox(String, DebugConfig, Object...)}. Leaving the scope is achieved via
      * {@link #close()}.
      */
@@ -163,12 +163,33 @@
      * }
      * </pre>
      * 
+     * The {@code name} argument is subject to the following type based conversion before having
+     * {@link Object#toString()} called on it:
+     * 
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     * 
      * @param name the name of the new scope
-     * @param context objects to be appended to the {@linkplain #context() current} debug context
      * @return the scope entered by this method which will be exited when its {@link Scope#close()}
      *         method is called
      */
-    public static Scope scope(Object name, Object... context) {
+    public static Scope scope(Object name) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see #scope(Object)
+     * @param context an object to be appended to the {@linkplain #context() current} debug context
+     */
+    public static Scope scope(Object name, Object context) {
         if (ENABLED) {
             return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context);
         } else {
@@ -177,6 +198,38 @@
     }
 
     /**
+     * @see #scope(Object)
+     * @param context1 first object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context2 second object to be appended to the {@linkplain #context() current} debug
+     *            context
+     */
+    public static Scope scope(Object name, Object context1, Object context2) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see #scope(Object)
+     * @param context1 first object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context2 second object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context3 third object to be appended to the {@linkplain #context() current} debug
+     *            context
+     */
+    public static Scope scope(Object name, Object context1, Object context2, Object context3) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2, context3);
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Creates and enters a new debug scope which will be disjoint from the current debug scope.
      * <p>
      * It is recommended to use the try-with-resource statement for managing entering and leaving
@@ -222,10 +275,10 @@
     /**
      * Handles an exception in the context of the debug scope just exited. The just exited scope
      * must have the current scope as its parent which will be the case if the try-with-resource
-     * pattern recommended by {@link #scope(String, Object...)} and
+     * pattern recommended by {@link #scope(Object)} and
      * {@link #sandbox(String, DebugConfig, Object...)} is used
      * 
-     * @see #scope(String, Object...)
+     * @see #scope(Object)
      * @see #sandbox(String, DebugConfig, Object...)
      */
     public static RuntimeException handle(Throwable exception) {
@@ -243,20 +296,79 @@
     }
 
     /**
-     * Prints an indented message to the current debug scopes's logging stream if logging is enabled
-     * in the scope.
+     * Prints a message to the current debug scope's logging stream if logging is enabled.
+     * 
+     * @param msg the message to log
+     */
+    public static void log(String msg) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(msg);
+        }
+    }
+
+    /**
+     * Prints a message to the current debug scope's logging stream if logging is enabled.
      * 
-     * @param msg The format string of the log message
-     * @param args The arguments referenced by the log message string
-     * @see Indent#log
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     */
+    public static void log(String format, Object arg) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(format, arg);
+        }
+    }
+
+    /**
+     * @see #log(String, Object)
+     */
+    public static void log(String format, Object arg1, Object arg2) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(format, arg1, arg2);
+        }
+    }
+
+    /**
+     * @see #log(String, Object)
      */
-    public static void log(String msg, Object... args) {
+    public static void log(String format, Object arg1, Object arg2, Object arg3) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(format, arg1, arg2, arg3);
+        }
+    }
+
+    /**
+     * @see #log(String, Object)
+     */
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) {
         if (ENABLED) {
-            DebugScope.getInstance().log(msg, args);
+            DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4);
+        }
+    }
+
+    /**
+     * @see #log(String, Object)
+     */
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5);
         }
     }
 
     /**
+     * Prints a message to the current debug scope's logging stream. This method must only be called
+     * if debugging is {@linkplain Debug#isEnabled() enabled}.
+     * 
+     * @param format a format string
+     * @param args the arguments referenced by the format specifiers in {@code format}
+     */
+    public static void logv(String format, Object... args) {
+        if (!ENABLED) {
+            throw new InternalError("Use of Debug.logv() must be guarded by a test of Debug.isEnabled()");
+        }
+        DebugScope.getInstance().log(format, args);
+    }
+
+    /**
      * The same as {@link #log}, but without line termination and without indentation.
      */
     public static void printf(String msg, Object... args) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Thu Mar 20 00:16:39 2014 +0100
@@ -28,10 +28,7 @@
 public interface DebugConfig {
 
     /**
-     * Determines if logging is enabled in the {@linkplain Debug#currentScope() current debug scope}
-     * .
-     * 
-     * @see Debug#log(String, Object...)
+     * Determines if logging is on in the {@linkplain Debug#currentScope() current debug scope} .
      */
     boolean isLogEnabled();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java	Thu Mar 20 00:16:39 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.logging;
 
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
@@ -94,16 +95,15 @@
         }
     }
 
-    // CheckStyle: stop system..print check
     protected void print() {
         long sum = 0;
+        PrintStream out = System.out;
         for (Map.Entry<Method, AtomicLong> entry : calls.entrySet()) {
             Method method = entry.getKey();
             long count = entry.getValue().get();
             sum += count;
-            System.out.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count);
+            out.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count);
         }
-        System.out.println(delegate.getClass().getSimpleName() + " calls: " + sum);
+        out.println(delegate.getClass().getSimpleName() + " calls: " + sum);
     }
-    // CheckStyle: resume system..print check
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Thu Mar 20 00:16:39 2014 +0100
@@ -748,7 +748,7 @@
                     int blockID = block.blockID;
                     // log statements in IFs because debugLiveX creates a new String
                     if (Debug.isLogEnabled()) {
-                        Debug.log("  start B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID),
+                        Debug.logv("  start B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID),
                                         debugLiveGen(blockID), debugLiveKill(blockID));
                     }
 
@@ -767,7 +767,7 @@
                     if (blockChanged) {
                         updateLiveness(blockID);
                         if (Debug.isLogEnabled()) {
-                            Debug.log("  end   B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID),
+                            Debug.logv("  end   B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID),
                                             debugLiveGen(blockID), debugLiveKill(blockID));
                         }
                     }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/System_setOut.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/System_setOut.java	Thu Mar 20 00:16:39 2014 +0100
@@ -46,19 +46,18 @@
         return sum;
     }
 
-    // CheckStyle: stop system..print check
     private static void doPrint(int n) {
+        PrintStream out = System.out;
         for (int i = 0; i < n; i++) {
-            System.out.print('x');
+            out.print('x');
         }
     }
 
     public static void main(String[] args) throws Exception {
-        System.out.println(test(10000));
+        PrintStream out = System.out;
+        out.println(test(10000));
     }
 
-    // CheckStyle: resume system..print check
-
     @LongTest
     public void run0() throws Throwable {
         runTest("test", 10000);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java	Thu Mar 20 00:16:39 2014 +0100
@@ -26,8 +26,8 @@
 
 /**
  * A name whose {@link String} value is computed only when it is needed. This is useful in
- * combination with debugging facilities such as {@link Debug#scope(CharSequence, Object...)} where
- * the {@link String} value of a name is only needed if debugging is enabled.
+ * combination with debugging facilities such as {@link Debug#scope(Object)} where the
+ * {@link String} value of a name is only needed if debugging is enabled.
  */
 public abstract class LazyName implements CharSequence {
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java	Thu Mar 20 00:16:39 2014 +0100
@@ -293,9 +293,8 @@
         }
 
         void warning(int offset, String message) {
-            // CheckStyle: stop system..print check
-            System.err.println("Warning: " + errorMessage(offset, message));
-            // CheckStyle: resume system..print check
+            PrintStream err = System.err;
+            err.println("Warning: " + errorMessage(offset, message));
         }
 
         String errorMessage(int offset, String message) {
@@ -323,10 +322,9 @@
             int lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1;
 
             String l = input.substring(lineStart, lineStart + 10);
-            // CheckStyle: stop system..print check
-            System.out.println("YYY" + input.substring(index, index + 10) + "...");
-            System.out.println("XXX" + l + "...");
-            // CheckStyle: resume system..print check
+            PrintStream out = System.out;
+            out.println("YYY" + input.substring(index, index + 10) + "...");
+            out.println("XXX" + l + "...");
 
             int pos = input.indexOf(HexCodeFile.NEW_LINE, 0);
             int line = 1;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Thu Mar 20 00:16:39 2014 +0100
@@ -100,7 +100,7 @@
 
         final StructuredGraph graph = new StructuredGraph(executeHelperMethod);
 
-        try (Scope s = Debug.scope("createGraph", graph)) {
+        try (Scope s = Debug.scope("CreateGraph", graph)) {
             new GraphBuilderPhase.Instance(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph);
 
             // Replace thisNode with constant.
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java	Thu Mar 20 00:16:39 2014 +0100
@@ -24,6 +24,8 @@
 
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
+import java.io.*;
+
 public class TimedCompilationPolicy extends DefaultCompilationPolicy {
 
     @Override
@@ -39,9 +41,8 @@
             // maybe introduce another method?
             profile.reportTiminingFailed(timestamp);
             if (TruffleCompilationDecisionTimePrintFail.getValue()) {
-                // Checkstyle: stop
-                System.out.println(profile.getName() + ": timespan  " + (timespan / 1000000) + " ms  larger than threshold");
-                // Checkstyle: resume
+                PrintStream out = System.out;
+                out.println(profile.getName() + ": timespan  " + (timespan / 1000000) + " ms  larger than threshold");
             }
         }
         return false;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Thu Mar 20 00:16:39 2014 +0100
@@ -117,7 +117,7 @@
 
         lastUsed.put(key, counter++);
         cache.put(key, markerGraph);
-        try (Scope s = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method})) {
+        try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) {
 
             final StructuredGraph graph = new StructuredGraph(method);
             final PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Thu Mar 20 00:16:39 2014 +0100
@@ -30,7 +30,7 @@
 
 /**
  * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in
- * {@linkplain Debug#scope(String, Object...) debug scopes}.
+ * {@linkplain Debug#scope(Object) debug scopes}.
  */
 public class TruffleDebugJavaMethod implements JavaMethod {
     private final RootCallTarget compilable;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Thu Mar 20 00:16:39 2014 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.debug.Debug.*;
+
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
@@ -59,8 +61,7 @@
     public boolean runAnalysis(final StructuredGraph graph, final PhaseContextT context) {
         boolean changed = false;
         for (int iteration = 0; iteration < maxIterations; iteration++) {
-
-            try (Scope s = Debug.scope("iteration " + iteration)) {
+            try (Scope s = Debug.scope(isEnabled() ? "iteration " + iteration : null)) {
                 SchedulePhase schedule = new SchedulePhase();
                 schedule.apply(graph, false);
                 Closure<?> closure = createEffectsClosure(context, schedule);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Thu Mar 20 00:15:49 2014 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Thu Mar 20 00:16:39 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.debug.Debug.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
@@ -54,7 +55,7 @@
 
     private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) {
         for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue(); iteration++) {
-            try (Scope s = Debug.scope("iteration " + iteration)) {
+            try (Scope s = Debug.scope(isEnabled() ? "iteration " + iteration : null)) {
                 boolean progress = false;
                 PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer);
                 boolean eaResult = ea.runAnalysis(graph, context);
--- a/mx/projects	Thu Mar 20 00:15:49 2014 +0100
+++ b/mx/projects	Thu Mar 20 00:16:39 2014 +0100
@@ -38,6 +38,10 @@
 library@OKRA_WITH_SIM@sourcePath=lib/okra-1.8-with-sim-src.jar
 library@OKRA_WITH_SIM@sourceUrls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-with-sim-src.jar
 
+library@JAVA_ALLOCATION_INSTRUMENTER@path=lib/java-allocation-instrumenter.jar
+library@JAVA_ALLOCATION_INSTRUMENTER@urls=http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter.jar
+library@JAVA_ALLOCATION_INSTRUMENTER@sha1=1cd4073f57d7d461a53b0ddc1ea4ee2aa0c60e66
+
 distribution@GRAAL@path=graal.jar
 distribution@GRAAL@dependencies=\
 com.oracle.graal.hotspot.amd64,\
@@ -519,7 +523,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=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime,com.oracle.graal.baseline
+project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime,com.oracle.graal.baseline,JAVA_ALLOCATION_INSTRUMENTER
 project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.test@javaCompliance=1.7
 project@com.oracle.graal.compiler.test@workingSets=Graal,Test