Mercurial > hg > graal-jvmci-8
changeset 22313:2c87ecb88c81
Merge with basic-graal
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 24 Jul 2015 02:11:18 +0200 |
parents | a12693d78272 (current diff) baa6dc00fd5c (diff) |
children | cd04ef3c7c49 |
files | jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ArithmeticOperation.java jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/TypeCheckHints.java jvmci/jdk.internal.jvmci.compiler/src/jdk/internal/jvmci/compiler/CompilerThread.java jvmci/jdk.internal.jvmci.compiler/src/jdk/internal/jvmci/compiler/CompilerThreadFactory.java jvmci/jdk.internal.jvmci.debug.test/src/jdk/internal/jvmci/debug/test/DebugHistogramTest.java jvmci/jdk.internal.jvmci.debug.test/src/jdk/internal/jvmci/debug/test/DebugTimerTest.java jvmci/jdk.internal.jvmci.debug/overview.html jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/AnsiColor.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Debug.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugCloseable.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfig.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfigCustomizer.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfigScope.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugDumpHandler.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugDumpScope.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugEnvironment.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugFilter.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugHistogram.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugInitializationPropertyProvider.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugMemUseTracker.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugMetric.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugTimer.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugVerifyHandler.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DelegatingDebugConfig.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Fingerprint.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Indent.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/JVMCIDebugConfig.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/JavaMethodContex.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/MethodFilter.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/TopLevelDebugConfig.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/AccumulatedDebugValue.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/CloseableCounterImpl.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramAsciiPrinter.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramImpl.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramRPrinter.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugScope.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugValue.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugValueMap.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/KeyRegistry.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/MemUseTrackerImpl.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/MetricImpl.java jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/TimerImpl.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilationStatistics.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilationTask.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompileTheWorld.java make/jvmci.make make/solaris/makefiles/mapfile-vers-JVMCI mx.jvmci/mx_jvmci.py mx.jvmci/suite.py |
diffstat | 206 files changed, 7491 insertions(+), 7087 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, 2015, 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.common; + +import static com.oracle.graal.compiler.common.BackendOptions.UserOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; +import jdk.internal.jvmci.options.*; +import jdk.internal.jvmci.options.DerivedOptionValue.*; + +/** + * Options to control the backend configuration. + */ +public final class BackendOptions { + + public static class UserOptions { + // @formatter:off + @Option(help = "Destruct SSA LIR eagerly (before other LIR phases).", type = OptionType.Debug) + public static final OptionValue<Boolean> LIREagerSSADestruction = new OptionValue<>(false); + // @formatter:on + } + + /* Create SSA LIR during LIR generation. */ + public static final DerivedOptionValue<Boolean> ConstructionSSAlirDuringLirBuilding = new DerivedOptionValue<>(new OptionSupplier<Boolean>() { + private static final long serialVersionUID = 7657622005438210681L; + + public Boolean get() { + return SSA_LIR.getValue(); + } + }); + + public enum LSRAVariant { + NONSSA_LSAR, + SSA_LSRA + } + + public static final DerivedOptionValue<LSRAVariant> LinearScanVariant = new DerivedOptionValue<>(new OptionSupplier<LSRAVariant>() { + private static final long serialVersionUID = 364925071685235153L; + + public LSRAVariant get() { + if (SSA_LIR.getValue() && !LIREagerSSADestruction.getValue()) { + return LSRAVariant.SSA_LSRA; + } + return LSRAVariant.NONSSA_LSAR; + } + }); + + /* Does the backend emit stack to stack moves?. */ + public static final DerivedOptionValue<Boolean> ShouldOptimizeStackToStackMoves = new DerivedOptionValue<>(new OptionSupplier<Boolean>() { + private static final long serialVersionUID = 2366072840509944317L; + + public Boolean get() { + switch (LinearScanVariant.getValue()) { + case SSA_LSRA: + return true; + } + return false; + } + }); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, 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; + +import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; +import com.oracle.graal.debug.*; + +/** + * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the + * context of a thread-local {@linkplain JVMCIDebugConfig debug configuration}. + */ +public class CompilerThread extends Thread { + + private final DebugConfigAccess debugConfigAccess; + + public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { + super(r); + this.setName(namePrefix + "-" + this.getId()); + this.setPriority(Thread.MAX_PRIORITY); + this.setDaemon(true); + this.debugConfigAccess = debugConfigAccess; + } + + @Override + public void run() { + JVMCIDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); + setContextClassLoader(getClass().getClassLoader()); + try { + super.run(); + } finally { + if (debugConfig != null) { + for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { + try { + dumpHandler.close(); + } catch (Throwable t) { + } + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler; + +import java.util.concurrent.*; + +import com.oracle.graal.debug.*; + +/** + * Facility for creating {@linkplain CompilerThread compiler threads}. + */ +public class CompilerThreadFactory implements ThreadFactory { + + /** + * Capability to get a thread-local debug configuration for the current thread. + */ + public interface DebugConfigAccess { + /** + * Get a thread-local debug configuration for the current thread. This will be null if + * debugging is disabled. + */ + JVMCIDebugConfig getDebugConfig(); + } + + protected final String threadNamePrefix; + protected final DebugConfigAccess debugConfigAccess; + + public CompilerThreadFactory(String threadNamePrefix, DebugConfigAccess debugConfigAccess) { + this.threadNamePrefix = threadNamePrefix; + this.debugConfigAccess = debugConfigAccess; + } + + public Thread newThread(Runnable r) { + return new CompilerThread(r, threadNamePrefix, debugConfigAccess); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.test; + +import java.io.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; + +import org.junit.*; + +public class DebugHistogramTest { + + @Test + public void testEmptyHistogram() { + DebugHistogram histogram = Debug.createHistogram("TestHistogram"); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); + String line = outputStream.toString().split("\r?\n")[0]; + Assert.assertEquals("TestHistogram is empty.", line); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + Assert.assertEquals("", outputStream.toString()); + } + + @Test + public void testSingleEntryHistogram() { + DebugHistogram histogram = Debug.createHistogram("TestHistogram"); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + histogram.add(new Integer(1)); + histogram.add(new Integer(1)); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); + String[] lines = outputStream.toString().split("\r?\n"); + // @formatter:off + String[] expected = { + "TestHistogram has 1 unique elements and 2 total elements:", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + "| 1 | 2 | ==================================================================================================== |", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + lines = outputStream.toString().split("\r?\n"); + // @formatter:off + expected = new String[] { + "TestHistogram <- c(2);", + "names(TestHistogram) <- c(\"1\");" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + } + + @Test + public void testMultipleEntryHistogram() { + DebugHistogram histogram = Debug.createHistogram("TestHistogram"); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + histogram.add(new Integer(1)); + histogram.add(new Integer(2)); + histogram.add(new Integer(2)); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); + String[] lines = outputStream.toString().split("\r?\n"); + // @formatter:off + String[] expected = new String[] { + "TestHistogram has 2 unique elements and 3 total elements:", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + "| 2 | 2 | ==================================================================================================== |", + "| 1 | 1 | ================================================== |", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + lines = outputStream.toString().split("\r?\n"); + // @formatter:off + expected = new String[] { + "TestHistogram <- c(2, 1);", + "names(TestHistogram) <- c(\"2\", \"1\");" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + } + + @Test + public void testTooLongValueString() { + DebugHistogram histogram = Debug.createHistogram("TestHistogram"); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + histogram.add("MyCustomValue"); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10, 1).print(histogram); + String[] lines = outputStream.toString().split("\r?\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]); + Assert.assertEquals("----------------------------------------", lines[1]); + Assert.assertEquals("| MyCusto... | 1 | ========== |", lines[2]); + Assert.assertEquals("----------------------------------------", lines[3]); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013, 2015, 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.debug.test; + +import static org.junit.Assert.*; + +import java.lang.management.*; + +import jdk.internal.jvmci.debug.*; + +import com.oracle.graal.debug.*; + +import org.junit.*; + +public class DebugTimerTest { + + private static final ThreadMXBean threadMXBean = Management.getThreadMXBean(); + + @Before + public void checkCapabilities() { + Assume.assumeTrue("skipping management interface test", threadMXBean.isCurrentThreadCpuTimeSupported()); + } + + /** + * Actively spins the current thread for at least a given number of milliseconds in such a way + * that timers for the current thread keep ticking over. + * + * @return the number of milliseconds actually spent spinning which is guaranteed to be >= + * {@code ms} + */ + private static long spin(long ms) { + long start = threadMXBean.getCurrentThreadCpuTime(); + do { + long durationMS = (threadMXBean.getCurrentThreadCpuTime() - start) / 1000; + if (durationMS >= ms) { + return durationMS; + } + } while (true); + } + + @Test + public void test1() { + DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); + try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { + + DebugTimer timerA = Debug.timer("TimerA"); + DebugTimer timerB = Debug.timer("TimerB"); + + long spinA; + long spinB; + + try (DebugCloseable a1 = timerA.start()) { + spinA = spin(50); + try (DebugCloseable b1 = timerB.start()) { + spinB = spin(50); + } + } + + Assert.assertTrue(timerB.getCurrentValue() < timerA.getCurrentValue()); + if (timerA.getFlat() != null && timerB.getFlat() != null) { + assertTrue(spinB >= spinA || timerB.getFlat().getCurrentValue() < timerA.getFlat().getCurrentValue()); + assertEquals(timerA.getFlat().getCurrentValue(), timerA.getCurrentValue() - timerB.getFlat().getCurrentValue(), 10D); + } + } + } + + @Test + public void test2() { + DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); + try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { + DebugTimer timerC = Debug.timer("TimerC"); + try (DebugCloseable c1 = timerC.start()) { + spin(50); + try (DebugCloseable c2 = timerC.start()) { + spin(50); + try (DebugCloseable c3 = timerC.start()) { + spin(50); + try (DebugCloseable c4 = timerC.start()) { + spin(50); + try (DebugCloseable c5 = timerC.start()) { + spin(50); + } + } + } + } + } + if (timerC.getFlat() != null) { + assertEquals(timerC.getFlat().getCurrentValue(), timerC.getCurrentValue()); + } + } + } + + @Test + public void test3() { + DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); + try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { + + DebugTimer timerD = Debug.timer("TimerD"); + DebugTimer timerE = Debug.timer("TimerE"); + + long spinD1; + long spinE; + + try (DebugCloseable d1 = timerD.start()) { + spinD1 = spin(50); + try (DebugCloseable e1 = timerE.start()) { + spinE = spin(50); + try (DebugCloseable d2 = timerD.start()) { + spin(50); + try (DebugCloseable d3 = timerD.start()) { + spin(50); + } + } + } + } + + Assert.assertTrue(timerE.getCurrentValue() < timerD.getCurrentValue()); + if (timerD.getFlat() != null && timerE.getFlat() != null) { + assertTrue(spinE >= spinD1 || timerE.getFlat().getCurrentValue() < timerD.getFlat().getCurrentValue()); + assertEquals(timerD.getFlat().getCurrentValue(), timerD.getCurrentValue() - timerE.getFlat().getCurrentValue(), 10D); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/overview.html Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,36 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- + +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. Oracle designates this +particular file as subject to the "Classpath" exception as provided +by Oracle in the LICENSE file that accompanied this code. + +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. +--> + +</head> +<body> + +Documentation for the <code>com.oracle.graal.debug</code> project. + +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/AnsiColor.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, 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.debug; + +/** + * Ansi terminal color escape codes. + */ +public final class AnsiColor { + /** Foreground black. */ + public static final String BLACK = "\u001b[30m"; + /** Foreground red. */ + public static final String RED = "\u001b[31m"; + /** Foreground green. */ + public static final String GREEN = "\u001b[32m"; + /** Foreground yellow. */ + public static final String YELLOW = "\u001b[33m"; + /** Foreground blue. */ + public static final String BLUE = "\u001b[34m"; + /** Foreground magenta. */ + public static final String MAGENTA = "\u001b[35m"; + /** Foreground cyan. */ + public static final String CYAN = "\u001b[36m"; + /** Foreground white. */ + public static final String WHITE = "\u001b[37m"; + + /** Foreground bold black. */ + public static final String BOLD_BLACK = "\u001b[30;1m"; + /** Foreground bold red. */ + public static final String BOLD_RED = "\u001b[31;1m"; + /** Foreground bold green. */ + public static final String BOLD_GREEN = "\u001b[32;1m"; + /** Foreground bold yellow. */ + public static final String BOLD_YELLOW = "\u001b[33;1m"; + /** Foreground bold blue. */ + public static final String BOLD_BLUE = "\u001b[34;1m"; + /** Foreground bold magenta. */ + public static final String BOLD_MAGENTA = "\u001b[35;1m"; + /** Foreground bold cyan. */ + public static final String BOLD_CYAN = "\u001b[36;1m"; + /** Foreground bold white. */ + public static final String BOLD_WHITE = "\u001b[37;1m"; + + /** Background black. */ + public static final String BG_BLACK = "\u001b[40m"; + /** Background red. */ + public static final String BG_RED = "\u001b[41m"; + /** Background green. */ + public static final String BG_GREEN = "\u001b[42m"; + /** Background yellow. */ + public static final String BG_YELLOW = "\u001b[43m"; + /** Background blue. */ + public static final String BG_BLUE = "\u001b[44m"; + /** Background magenta. */ + public static final String BG_MAGENTA = "\u001b[45m"; + /** Background cyan. */ + public static final String BG_CYAN = "\u001b[46m"; + /** Background white. */ + public static final String BG_WHITE = "\u001b[47m"; + + /** Reset. */ + public static final String RESET = "\u001b[0m"; + /** Underline. */ + public static final String UNDERLINED = "\u001b[4m"; + + /** Prevent instantiation. */ + private AnsiColor() { + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,1551 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import static java.util.FormattableFlags.*; +import static com.oracle.graal.debug.Debug.Initialization.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + +import java.io.*; +import java.util.*; +import java.util.concurrent.*; + +import com.oracle.graal.debug.DelegatingDebugConfig.*; +import com.oracle.graal.debug.internal.*; +import jdk.internal.jvmci.service.*; + +/** + * Scope based debugging facility. This facility is {@link #isEnabled()} if assertions are enabled + * for the {@link Debug} class or the {@value Initialization#INITIALIZER_PROPERTY_NAME} system + * property is {@code "true"} when {@link Debug} is initialized. + */ +public class Debug { + + static { + for (DebugInitializationPropertyProvider p : Services.load(DebugInitializationPropertyProvider.class)) { + p.apply(); + } + } + + /** + * Class to assist with initialization of {@link Debug}. + */ + public static class Initialization { + + public static final String INITIALIZER_PROPERTY_NAME = "jvmci.debug.enable"; + + private static boolean initialized; + + /** + * Determines if {@link Debug} has been initialized. + */ + public static boolean isDebugInitialized() { + return initialized; + } + + } + + @SuppressWarnings("all") + private static boolean initialize() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + Initialization.initialized = true; + return assertionsEnabled || Boolean.getBoolean(INITIALIZER_PROPERTY_NAME); + } + + private static final boolean ENABLED = initialize(); + + public static boolean isEnabled() { + return ENABLED; + } + + public static boolean isDumpEnabledForMethod() { + if (!ENABLED) { + return false; + } + DebugConfig config = DebugScope.getConfig(); + if (config == null) { + return false; + } + return config.isDumpEnabledForMethod(); + } + + public static final int DEFAULT_LOG_LEVEL = 2; + + public static boolean isDumpEnabled() { + return isDumpEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isDumpEnabled(int dumpLevel) { + return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel); + } + + /** + * Determines if verification is enabled in the current method, regardless of the + * {@linkplain Debug#currentScope() current debug scope}. + * + * @see Debug#verify(Object, String) + */ + public static boolean isVerifyEnabledForMethod() { + if (!ENABLED) { + return false; + } + DebugConfig config = DebugScope.getConfig(); + if (config == null) { + return false; + } + return config.isVerifyEnabledForMethod(); + } + + /** + * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug + * scope}. + * + * @see Debug#verify(Object, String) + */ + public static boolean isVerifyEnabled() { + return ENABLED && DebugScope.getInstance().isVerifyEnabled(); + } + + public static boolean isMeterEnabled() { + return ENABLED && DebugScope.getInstance().isMeterEnabled(); + } + + public static boolean isTimeEnabled() { + return ENABLED && DebugScope.getInstance().isTimeEnabled(); + } + + public static boolean isMemUseTrackingEnabled() { + return ENABLED && DebugScope.getInstance().isMemUseTrackingEnabled(); + } + + public static boolean isLogEnabledForMethod() { + if (!ENABLED) { + return false; + } + DebugConfig config = DebugScope.getConfig(); + if (config == null) { + return false; + } + return config.isLogEnabledForMethod(); + } + + public static boolean isLogEnabled() { + return isLogEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isLogEnabled(int logLevel) { + return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel); + } + + @SuppressWarnings("unused") + public static Runnable decorateDebugRoot(Runnable runnable, String name, DebugConfig config) { + return runnable; + } + + @SuppressWarnings("unused") + public static <T> Callable<T> decorateDebugRoot(Callable<T> callable, String name, DebugConfig config) { + return callable; + } + + @SuppressWarnings("unused") + public static Runnable decorateScope(Runnable runnable, String name, Object... context) { + return runnable; + } + + @SuppressWarnings("unused") + public static <T> Callable<T> decorateScope(Callable<T> callable, String name, Object... context) { + return callable; + } + + /** + * Gets a string composed of the names in the current nesting of debug + * {@linkplain #scope(Object) scopes} separated by {@code '.'}. + */ + public static String currentScope() { + if (ENABLED) { + return DebugScope.getInstance().getQualifiedName(); + } else { + return ""; + } + } + + /** + * Represents a debug scope entered by {@link Debug#scope(Object)} or + * {@link Debug#sandbox(CharSequence, DebugConfig, Object...)}. Leaving the scope is achieved + * via {@link #close()}. + */ + public interface Scope extends AutoCloseable { + void close(); + } + + /** + * Creates and enters a new debug scope which will be a child of the current debug scope. + * <p> + * It is recommended to use the try-with-resource statement for managing entering and leaving + * debug scopes. For example: + * + * <pre> + * try (Scope s = Debug.scope("InliningGraph", inlineeGraph)) { + * ... + * } catch (Throwable e) { + * throw Debug.handle(e); + * } + * </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 contextObjects an array of object to be appended to the {@linkplain #context() + * current} debug context + * @throws Throwable used to enforce a catch block. + * @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[] contextObjects) throws Throwable { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, contextObjects); + } else { + return null; + } + } + + /** + * Similar to {@link #scope(Object, Object[])} but without context objects. Therefore the catch + * block can be omitted. + * + * @see #scope(Object, Object[]) + */ + public static Scope scope(Object name) { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null); + } else { + return null; + } + } + + /** + * @see #scope(Object, Object[]) + * @param context an object to be appended to the {@linkplain #context() current} debug context + */ + public static Scope scope(Object name, Object context) throws Throwable { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context); + } else { + return null; + } + } + + /** + * @see #scope(Object, 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) throws Throwable { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2); + } else { + return null; + } + } + + /** + * @see #scope(Object, 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) throws Throwable { + 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 + * debug scopes. For example: + * + * <pre> + * try (Scope s = Debug.sandbox("CompilingStub", null, stubGraph)) { + * ... + * } catch (Throwable e) { + * throw Debug.handle(e); + * } + * </pre> + * + * @param name the name of the new scope + * @param config the debug configuration to use for 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 sandbox(CharSequence name, DebugConfig config, Object... context) throws Throwable { + if (ENABLED) { + DebugConfig sandboxConfig = config == null ? silentConfig() : config; + return DebugScope.getInstance().scope(name, sandboxConfig, context); + } else { + return null; + } + } + + public static Scope forceLog() throws Throwable { + ArrayList<Object> context = new ArrayList<>(); + for (Object obj : context()) { + context.add(obj); + } + return Debug.sandbox("forceLog", new DelegatingDebugConfig().override(Level.LOG, Integer.MAX_VALUE).enable(LOG_METHOD), context.toArray()); + } + + /** + * Opens a scope in which exception {@linkplain DebugConfig#interceptException(Throwable) + * interception} is disabled. It is recommended to use the try-with-resource statement for + * managing entering and leaving such scopes: + * + * <pre> + * try (DebugConfigScope s = Debug.disableIntercept()) { + * ... + * } + * </pre> + * + * This is particularly useful to suppress extraneous output in JUnit tests that are expected to + * throw an exception. + */ + public static DebugConfigScope disableIntercept() { + return Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); + } + + /** + * 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(Object)} and + * {@link #sandbox(CharSequence, DebugConfig, Object...)} is used + * + * @see #scope(Object, Object[]) + * @see #sandbox(CharSequence, DebugConfig, Object...) + */ + public static RuntimeException handle(Throwable exception) { + if (ENABLED) { + return DebugScope.getInstance().handle(exception); + } else { + if (exception instanceof Error) { + throw (Error) exception; + } + if (exception instanceof RuntimeException) { + throw (RuntimeException) exception; + } + throw new RuntimeException(exception); + } + } + + public static void log(String msg) { + log(DEFAULT_LOG_LEVEL, msg); + } + + /** + * 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(int logLevel, String msg) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, msg); + } + } + + public static void log(String format, Object arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * Prints a message to the current debug scope's logging stream if logging is enabled. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + */ + public static void log(int logLevel, String format, Object arg) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg); + } + } + + public static void log(String format, int arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * Prints a message to the current debug scope's logging stream if logging is enabled. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + */ + public static void log(int logLevel, String format, int arg) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg); + } + } + + public static void log(String format, Object arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, int arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, Object arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, Object arg1, int arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, int arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, int arg1, int arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, int arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, Object arg1, Object arg2, Object arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); + } + } + + public static void log(String format, int arg1, int arg2, int arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, int arg2, int arg3) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); + } + } + + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4); + } + } + + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5); + } + } + + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + } + + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + } + + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + } + + public static void logv(String format, Object... args) { + logv(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * Prints a message to the current debug scope's logging stream. This method must only be called + * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call + * site. If possible, call one of the other {@code log()} methods in this class that take a + * fixed number of parameters. + * + * @param format a format string + * @param args the arguments referenced by the format specifiers in {@code format} + */ + public static void logv(int logLevel, 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(logLevel, format, args); + } + + /** + * This override exists to catch cases when {@link #log(String, Object)} is called with one + * argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void log(String format, Object[] args) { + assert false : "shouldn't use this"; + log(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #log(int, String, Object)} is called with one + * argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void log(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logv(logLevel, format, args); + } + + public static void dump(Object object, String msg) { + dump(DEFAULT_LOG_LEVEL, object, msg); + } + + public static void dump(int dumpLevel, Object object, String msg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, msg); + } + } + + public static void dump(Object object, String format, Object arg) { + dump(DEFAULT_LOG_LEVEL, object, format, arg); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg); + } + } + + public static void dump(Object object, String format, Object arg1, Object arg2) { + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2); + } + } + + public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) { + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3); + } + } + + /** + * This override exists to catch cases when {@link #dump(Object, String, Object)} is called with + * one argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void dump(Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + dump(DEFAULT_LOG_LEVEL, object, format, args); + } + + /** + * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void dump(int dumpLevel, Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, args); + } + } + + /** + * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() + * config} to perform verification on a given object. + * + * @param object object to verify + * @param message description of verification context + * + * @see DebugVerifyHandler#verify(Object, String) + */ + public static void verify(Object object, String message) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, message); + } + } + + /** + * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() + * config} to perform verification on a given object. + * + * @param object object to verify + * @param format a format string for the description of the verification context + * @param arg the argument referenced by the format specifiers in {@code format} + * + * @see DebugVerifyHandler#verify(Object, String) + */ + public static void verify(Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, arg); + } + } + + /** + * This override exists to catch cases when {@link #verify(Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void verify(Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, args); + } + } + + /** + * Opens a new indentation level (by adding some spaces) based on the current indentation level. + * This should be used in a {@linkplain Indent try-with-resources} pattern. + * + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + * @see #logAndIndent(int, String) + * @see #logAndIndent(int, String, Object) + */ + public static Indent indent() { + if (ENABLED) { + DebugScope scope = DebugScope.getInstance(); + return scope.pushIndentLogger(); + } + return null; + } + + public static Indent logAndIndent(String msg) { + return logAndIndent(DEFAULT_LOG_LEVEL, msg); + } + + /** + * A convenience function which combines {@link #log(String)} and {@link #indent()}. + * + * @param msg the message to log + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + */ + public static Indent logAndIndent(int logLevel, String msg) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, msg); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + */ + public static Indent logAndIndent(int logLevel, String format, Object arg) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, int arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + */ + public static Indent logAndIndent(int logLevel, String format, int arg) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, int arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, Object arg2) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, int arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, int arg1, int arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); + } + return null; + } + + public static Indent logAndIndent(String format, int arg1, int arg2, int arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2, int arg3) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, int arg2, int arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2, int arg3) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + if (ENABLED && Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + return null; + } + + /** + * A convenience function which combines {@link #logv(int, String, Object...)} and + * {@link #indent()}. + * + * @param format a format string + * @param args the arguments referenced by the format specifiers in {@code format} + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + */ + public static Indent logvAndIndent(int logLevel, String format, Object... args) { + if (ENABLED) { + if (Debug.isLogEnabled(logLevel)) { + return logvAndIndentInternal(logLevel, format, args); + } + return null; + } + throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()"); + } + + private static Indent logvAndIndentInternal(int logLevel, String format, Object... args) { + assert ENABLED && Debug.isLogEnabled(logLevel) : "must have checked Debug.isLogEnabled()"; + DebugScope scope = DebugScope.getInstance(); + scope.log(logLevel, format, args); + return scope.pushIndentLogger(); + } + + /** + * This override exists to catch cases when {@link #logAndIndent(String, Object)} is called with + * one argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void logAndIndent(String format, Object[] args) { + assert false : "shouldn't use this"; + logAndIndent(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void logAndIndent(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logvAndIndent(logLevel, format, args); + } + + public static Iterable<Object> context() { + if (ENABLED) { + return DebugScope.getInstance().getCurrentContext(); + } else { + return Collections.emptyList(); + } + } + + @SuppressWarnings("unchecked") + public static <T> List<T> contextSnapshot(Class<T> clazz) { + if (ENABLED) { + List<T> result = new ArrayList<>(); + for (Object o : context()) { + if (clazz.isInstance(o)) { + result.add((T) o); + } + } + return result; + } else { + return Collections.emptyList(); + } + } + + /** + * Searches the current debug scope, bottom up, for a context object that is an instance of a + * given type. The first such object found is returned. + */ + @SuppressWarnings("unchecked") + public static <T> T contextLookup(Class<T> clazz) { + if (ENABLED) { + for (Object o : context()) { + if (clazz.isInstance(o)) { + return ((T) o); + } + } + } + return null; + } + + /** + * Creates a {@linkplain DebugMemUseTracker memory use tracker} that is enabled iff debugging is + * {@linkplain #isEnabled() enabled}. + * <p> + * A disabled tracker has virtually no overhead. + */ + public static DebugMemUseTracker memUseTracker(CharSequence name) { + if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { + return VOID_MEM_USE_TRACKER; + } + return createMemUseTracker("%s", name, null); + } + + /** + * Creates a debug memory use tracker. Invoking this method is equivalent to: + * + * <pre> + * Debug.memUseTracker(format, arg, null) + * </pre> + * + * except that the string formatting only happens if metering is enabled. + * + * @see #metric(String, Object, Object) + */ + public static DebugMemUseTracker memUseTracker(String format, Object arg) { + if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { + return VOID_MEM_USE_TRACKER; + } + return createMemUseTracker(format, arg, null); + } + + /** + * Creates a debug memory use tracker. Invoking this method is equivalent to: + * + * <pre> + * Debug.memUseTracker(String.format(format, arg1, arg2)) + * </pre> + * + * except that the string formatting only happens if memory use tracking is enabled. In + * addition, each argument is subject to the following type based conversion before being passed + * as an argument to {@link String#format(String, Object...)}: + * + * <pre> + * Type | Conversion + * ------------------+----------------- + * java.lang.Class | arg.getSimpleName() + * | + * </pre> + * + * @see #memUseTracker(CharSequence) + */ + public static DebugMemUseTracker memUseTracker(String format, Object arg1, Object arg2) { + if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { + return VOID_MEM_USE_TRACKER; + } + return createMemUseTracker(format, arg1, arg2); + } + + private static DebugMemUseTracker createMemUseTracker(String format, Object arg1, Object arg2) { + String name = formatDebugName(format, arg1, arg2); + return new MemUseTrackerImpl(name, !isUnconditionalMemUseTrackingEnabled); + } + + /** + * Creates a {@linkplain DebugMetric metric} that is enabled iff debugging is + * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to + * {@value #ENABLE_METRIC_PROPERTY_NAME_PREFIX} to {@code name} is + * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the + * returned metric is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is + * conditional. + * <p> + * A disabled metric has virtually no overhead. + */ + public static DebugMetric metric(CharSequence name) { + if (!areUnconditionalMetricsEnabled() && !ENABLED) { + return VOID_METRIC; + } + return createMetric("%s", name, null); + } + + public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { + if (flags == 0 && width < 0) { + return s; + } + StringBuilder sb = new StringBuilder(s); + + // apply width and justification + int len = sb.length(); + if (len < width) { + for (int i = 0; i < width - len; i++) { + if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) { + sb.append(' '); + } else { + sb.insert(0, ' '); + } + } + } + + String res = sb.toString(); + if ((flags & UPPERCASE) == UPPERCASE) { + res = res.toUpperCase(); + } + return res; + } + + /** + * Creates a debug metric. Invoking this method is equivalent to: + * + * <pre> + * Debug.metric(format, arg, null) + * </pre> + * + * except that the string formatting only happens if metering is enabled. + * + * @see #metric(String, Object, Object) + */ + public static DebugMetric metric(String format, Object arg) { + if (!areUnconditionalMetricsEnabled() && !ENABLED) { + return VOID_METRIC; + } + return createMetric(format, arg, null); + } + + /** + * Creates a debug metric. Invoking this method is equivalent to: + * + * <pre> + * Debug.metric(String.format(format, arg1, arg2)) + * </pre> + * + * except that the string formatting only happens if metering is enabled. In addition, each + * argument is subject to the following type based conversion before being passed as an argument + * to {@link String#format(String, Object...)}: + * + * <pre> + * Type | Conversion + * ------------------+----------------- + * java.lang.Class | arg.getSimpleName() + * | + * </pre> + * + * @see #metric(CharSequence) + */ + public static DebugMetric metric(String format, Object arg1, Object arg2) { + if (!areUnconditionalMetricsEnabled() && !ENABLED) { + return VOID_METRIC; + } + return createMetric(format, arg1, arg2); + } + + private static DebugMetric createMetric(String format, Object arg1, Object arg2) { + String name = formatDebugName(format, arg1, arg2); + boolean conditional = enabledMetrics == null || !findMatch(enabledMetrics, enabledMetricsSubstrings, name); + if (!ENABLED && conditional) { + return VOID_METRIC; + } + return new MetricImpl(name, conditional); + } + + /** + * Changes the debug configuration for the current thread. + * + * @param config new configuration to use for the current thread + * @return an object that when {@linkplain DebugConfigScope#close() closed} will restore the + * debug configuration for the current thread to what it was before this method was + * called + */ + public static DebugConfigScope setConfig(DebugConfig config) { + if (ENABLED) { + return new DebugConfigScope(config); + } else { + return null; + } + } + + /** + * Creates an object for counting value frequencies. + */ + public static DebugHistogram createHistogram(String name) { + return new DebugHistogramImpl(name); + } + + public static DebugConfig silentConfig() { + return fixedConfig(0, 0, false, false, false, false, Collections.<DebugDumpHandler> emptyList(), Collections.<DebugVerifyHandler> emptyList(), null); + } + + public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, + final boolean isVerifyEnabled, final Collection<DebugDumpHandler> dumpHandlers, final Collection<DebugVerifyHandler> verifyHandlers, final PrintStream output) { + return new DebugConfig() { + + @Override + public int getLogLevel() { + return logLevel; + } + + public boolean isLogEnabledForMethod() { + return logLevel > 0; + } + + @Override + public boolean isMeterEnabled() { + return isMeterEnabled; + } + + @Override + public boolean isMemUseTrackingEnabled() { + return isMemUseTrackingEnabled; + } + + @Override + public int getDumpLevel() { + return dumpLevel; + } + + public boolean isDumpEnabledForMethod() { + return dumpLevel > 0; + } + + @Override + public boolean isVerifyEnabled() { + return isVerifyEnabled; + } + + public boolean isVerifyEnabledForMethod() { + return isVerifyEnabled; + } + + @Override + public boolean isTimeEnabled() { + return isTimerEnabled; + } + + @Override + public RuntimeException interceptException(Throwable e) { + return null; + } + + @Override + public Collection<DebugDumpHandler> dumpHandlers() { + return dumpHandlers; + } + + @Override + public Collection<DebugVerifyHandler> verifyHandlers() { + return verifyHandlers; + } + + @Override + public PrintStream output() { + return output; + } + + @Override + public void addToContext(Object o) { + } + + @Override + public void removeFromContext(Object o) { + } + }; + } + + private static final DebugMetric VOID_METRIC = new DebugMetric() { + + public void increment() { + } + + public void add(long value) { + } + + public void setConditional(boolean flag) { + throw new InternalError("Cannot make void metric conditional"); + } + + public boolean isConditional() { + return false; + } + + public long getCurrentValue() { + return 0L; + } + }; + + private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() { + + public DebugCloseable start() { + return DebugCloseable.VOID_CLOSEABLE; + } + + public long getCurrentValue() { + return 0; + } + }; + + public static final String ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME = "jvmci.debug.unscopedTimers"; + public static final String ENABLE_UNSCOPED_METRICS_PROPERTY_NAME = "jvmci.debug.unscopedMetrics"; + public static final String ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME = "jvmci.debug.unscopedMemUseTrackers"; + + /** + * @see #timer(CharSequence) + */ + public static final String ENABLE_TIMER_PROPERTY_NAME_PREFIX = "jvmci.debug.timer."; + + /** + * @see #metric(CharSequence) + */ + public static final String ENABLE_METRIC_PROPERTY_NAME_PREFIX = "jvmci.debug.metric."; + + /** + * Set of unconditionally enabled metrics. Possible values and their meanings: + * <ul> + * <li>{@code null}: no unconditionally enabled metrics</li> + * <li>{@code isEmpty()}: all metrics are unconditionally enabled</li> + * <li>{@code !isEmpty()}: use {@link #findMatch(Set, Set, String)} on this set and + * {@link #enabledMetricsSubstrings} to determine which metrics are unconditionally enabled</li> + * </ul> + */ + private static final Set<String> enabledMetrics; + + /** + * Set of unconditionally enabled timers. Same interpretation of values as for + * {@link #enabledMetrics}. + */ + private static final Set<String> enabledTimers; + + private static final Set<String> enabledMetricsSubstrings = new HashSet<>(); + private static final Set<String> enabledTimersSubstrings = new HashSet<>(); + + /** + * Specifies if all mem use trackers are unconditionally enabled. + */ + private static final boolean isUnconditionalMemUseTrackingEnabled; + + static { + Set<String> metrics = new HashSet<>(); + Set<String> timers = new HashSet<>(); + parseMetricAndTimerSystemProperties(metrics, timers, enabledMetricsSubstrings, enabledTimersSubstrings); + metrics = metrics.isEmpty() && enabledMetricsSubstrings.isEmpty() ? null : metrics; + timers = timers.isEmpty() && enabledTimersSubstrings.isEmpty() ? null : timers; + if (metrics == null && Boolean.getBoolean(ENABLE_UNSCOPED_METRICS_PROPERTY_NAME)) { + metrics = Collections.emptySet(); + } + if (timers == null && Boolean.getBoolean(ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME)) { + timers = Collections.emptySet(); + } + enabledMetrics = metrics; + enabledTimers = timers; + isUnconditionalMemUseTrackingEnabled = Boolean.getBoolean(ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME); + } + + private static boolean findMatch(Set<String> haystack, Set<String> haystackSubstrings, String needle) { + if (haystack.isEmpty()) { + // Empty haystack means match all + return true; + } + if (haystack.contains(needle)) { + return true; + } + if (!haystackSubstrings.isEmpty()) { + for (String h : haystackSubstrings) { + if (needle.startsWith(h)) { + return true; + } + } + } + return false; + } + + public static boolean areUnconditionalTimersEnabled() { + return enabledTimers != null; + } + + public static boolean areUnconditionalMetricsEnabled() { + return enabledMetrics != null; + } + + protected static void parseMetricAndTimerSystemProperties(Set<String> metrics, Set<String> timers, Set<String> metricsSubstrings, Set<String> timersSubstrings) { + do { + try { + for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) { + String name = e.getKey().toString(); + if (name.startsWith(ENABLE_METRIC_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { + if (name.endsWith("*")) { + metricsSubstrings.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length(), name.length() - 1)); + } else { + metrics.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length())); + } + } + if (name.startsWith(ENABLE_TIMER_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { + if (name.endsWith("*")) { + timersSubstrings.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length(), name.length() - 1)); + } else { + timers.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length())); + } + } + } + return; + } catch (ConcurrentModificationException e) { + // Iterating over the system properties may race with another thread that is + // updating the system properties. Simply try again in this case. + } + } while (true); + } + + /** + * Creates a {@linkplain DebugTimer timer} that is enabled iff debugging is + * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to + * {@value #ENABLE_TIMER_PROPERTY_NAME_PREFIX} to {@code name} is + * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the + * returned timer is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is + * conditional. + * <p> + * A disabled timer has virtually no overhead. + */ + public static DebugTimer timer(CharSequence name) { + if (!areUnconditionalTimersEnabled() && !ENABLED) { + return VOID_TIMER; + } + return createTimer("%s", name, null); + } + + /** + * Creates a debug timer. Invoking this method is equivalent to: + * + * <pre> + * Debug.timer(format, arg, null) + * </pre> + * + * except that the string formatting only happens if timing is enabled. + * + * @see #timer(String, Object, Object) + */ + public static DebugTimer timer(String format, Object arg) { + if (!areUnconditionalTimersEnabled() && !ENABLED) { + return VOID_TIMER; + } + return createTimer(format, arg, null); + } + + /** + * Creates a debug timer. Invoking this method is equivalent to: + * + * <pre> + * Debug.timer(String.format(format, arg1, arg2)) + * </pre> + * + * except that the string formatting only happens if timing is enabled. In addition, each + * argument is subject to the following type based conversion before being passed as an argument + * to {@link String#format(String, Object...)}: + * + * <pre> + * Type | Conversion + * ------------------+----------------- + * java.lang.Class | arg.getSimpleName() + * | + * </pre> + * + * @see #timer(CharSequence) + */ + public static DebugTimer timer(String format, Object arg1, Object arg2) { + if (!areUnconditionalTimersEnabled() && !ENABLED) { + return VOID_TIMER; + } + return createTimer(format, arg1, arg2); + } + + /** + * There are paths where construction of formatted class names are common and the code below is + * surprisingly expensive, so compute it once and cache it. + */ + private static final ClassValue<String> formattedClassName = new ClassValue<String>() { + @Override + protected String computeValue(Class<?> c) { + final String simpleName = c.getSimpleName(); + Class<?> enclosingClass = c.getEnclosingClass(); + if (enclosingClass != null) { + String prefix = ""; + while (enclosingClass != null) { + prefix = enclosingClass.getSimpleName() + "_" + prefix; + enclosingClass = enclosingClass.getEnclosingClass(); + } + return prefix + simpleName; + } else { + return simpleName; + } + } + }; + + public static Object convertFormatArg(Object arg) { + if (arg instanceof Class) { + return formattedClassName.get((Class<?>) arg); + } + return arg; + } + + private static String formatDebugName(String format, Object arg1, Object arg2) { + return String.format(format, convertFormatArg(arg1), convertFormatArg(arg2)); + } + + private static DebugTimer createTimer(String format, Object arg1, Object arg2) { + String name = formatDebugName(format, arg1, arg2); + boolean conditional = enabledTimers == null || !findMatch(enabledTimers, enabledTimersSubstrings, name); + if (!ENABLED && conditional) { + return VOID_TIMER; + } + return new TimerImpl(name, conditional); + } + + private static final DebugTimer VOID_TIMER = new DebugTimer() { + + public DebugCloseable start() { + return DebugCloseable.VOID_CLOSEABLE; + } + + public void setConditional(boolean flag) { + throw new InternalError("Cannot make void timer conditional"); + } + + public boolean isConditional() { + return false; + } + + public long getCurrentValue() { + return 0L; + } + + public TimeUnit getTimeUnit() { + return null; + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugCloseable.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, 2015, 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.debug; + +/** + * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and + * adds the elapsed time since {@code start()} to the total for the timer. + */ +public interface DebugCloseable extends AutoCloseable { + + DebugCloseable VOID_CLOSEABLE = new DebugCloseable() { + + @Override + public void close() { + } + }; + + void close(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.io.*; +import java.util.*; + +public interface DebugConfig { + + /** + * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope} + * . + */ + int getLogLevel(); + + /** + * Determines the current dump level in the {@linkplain Debug#currentScope() current debug + * scope}. + */ + int getDumpLevel(); + + /** + * Determines if logging can be enabled in the current method, regardless of the + * {@linkplain Debug#currentScope() current debug scope}. + */ + boolean isLogEnabledForMethod(); + + /** + * Determines if metering is enabled in the {@linkplain Debug#currentScope() current debug + * scope}. + * + * @see Debug#metric(CharSequence) + */ + boolean isMeterEnabled(); + + /** + * Determines if memory use tracking is enabled in the {@linkplain Debug#currentScope() current + * debug scope}. + * + * @see Debug#memUseTracker(CharSequence) + */ + boolean isMemUseTrackingEnabled(); + + /** + * Determines if dumping can be enabled in the current method, regardless of the + * {@linkplain Debug#currentScope() current debug scope}. + */ + boolean isDumpEnabledForMethod(); + + /** + * @see Debug#isVerifyEnabled() + */ + boolean isVerifyEnabled(); + + /** + * @see Debug#isVerifyEnabledForMethod() + */ + boolean isVerifyEnabledForMethod(); + + /** + * Adds an object the context used by this configuration to do filtering. + */ + void addToContext(Object o); + + /** + * Removes an object the context used by this configuration to do filtering. + * + * This should only removes extra context added by {@link #addToContext(Object)}. + */ + void removeFromContext(Object o); + + /** + * @see Debug#timer(CharSequence) + */ + boolean isTimeEnabled(); + + /** + * Handles notification of an exception occurring within a debug scope. + * + * @return the exception object that is to be propagated to parent scope. A value of + * {@code null} indicates that {@code e} is to be propagated. + */ + RuntimeException interceptException(Throwable e); + + /** + * Gets the modifiable collection of dump handlers registered with this configuration. + */ + Collection<DebugDumpHandler> dumpHandlers(); + + PrintStream output(); + + /** + * Gets the modifiable collection of verify handlers registered with this configuration. + */ + Collection<DebugVerifyHandler> verifyHandlers(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigCustomizer.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015, 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.debug; + +public interface DebugConfigCustomizer { + void customize(DebugConfig config); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import com.oracle.graal.debug.internal.*; + +/** + * A utility for scoping a change to the current debug + * {@linkplain DebugScope#setConfig(DebugConfig) configuration}. For example: + * + * <pre> + * DebugConfig config = ...; + * try (DebugConfigScope s = new DebugConfigScope(config)) { + * // ... + * } + * </pre> + */ +public class DebugConfigScope implements AutoCloseable { + + private final DebugConfig current; + + /** + * Sets the current debug {@linkplain DebugScope#setConfig(DebugConfig) configuration} to a + * given value and creates an object that when {@linkplain #close() closed} resets the + * configuration to the {@linkplain DebugScope#getConfig() current} configuration. + */ + public DebugConfigScope(DebugConfig config) { + this.current = DebugScope.getConfig(); + DebugScope.getInstance().setConfig(config); + } + + public void close() { + DebugScope.getInstance().setConfig(current); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpHandler.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.io.*; + +public interface DebugDumpHandler extends Closeable { + + void dump(Object object, String message); + + /** + * Flushes and releases resources managed by this dump handler. A subsequent call to + * {@link #dump(Object, String)} will create and open new resources. That is, this method can be + * used to reset the handler. + */ + @Override + void close(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpScope.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +public class DebugDumpScope { + + public final String name; + + /** + * Specifies if this scope decorates an inner scope. A hierarchical or tree representation of + * nested scopes may choose to represent a decorator scope at the same level as the scope it + * decorates. + */ + public final boolean decorator; + + public DebugDumpScope(String name) { + this(name, false); + } + + public DebugDumpScope(String name, boolean decorator) { + this.name = name; + this.decorator = decorator; + } + + @Override + public String toString() { + return "DebugDumpScope[" + name + "]"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugEnvironment.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import static com.oracle.graal.debug.JVMCIDebugConfig.*; + +import java.io.*; +import java.util.*; + +import jdk.internal.jvmci.service.*; + +public class DebugEnvironment { + + public static JVMCIDebugConfig initialize(PrintStream log) { + + if (!Debug.isEnabled()) { + log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true"); + return null; + } + List<DebugDumpHandler> dumpHandlers = new ArrayList<>(); + List<DebugVerifyHandler> verifyHandlers = new ArrayList<>(); + JVMCIDebugConfig debugConfig = new JVMCIDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), Verify.getValue(), MethodFilter.getValue(), + log, dumpHandlers, verifyHandlers); + + for (DebugConfigCustomizer customizer : Services.load(DebugConfigCustomizer.class)) { + customizer.customize(debugConfig); + } + + Debug.setConfig(debugConfig); + return debugConfig; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugFilter.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.debug.internal.*; + +/** + * Implements the filter specified by the {@link JVMCIDebugConfig#Dump}, + * {@link JVMCIDebugConfig#Log}, {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} + * options. + * <p> + * These options enable the associated debug facility if their filter matches the + * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current + * scope}. For the {@link JVMCIDebugConfig#Dump} and {@link JVMCIDebugConfig#Log} options, the log + * or dump level is set. The {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} + * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} + * means enabled. + * <p> + * A filter is a list of comma-separated terms of the form {@code <pattern>[:<level>]}. + * {@code <pattern>} is interpreted as a glob pattern if it contains a "*" or "?" character. + * Otherwise, it is interpreted as a substring. If {@code <pattern>} is empty, it matches every + * scope. If {@code :<level>} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term + * {@code ~<pattern>} is a shorthand for {@code <pattern>:0} to disable a debug facility for a + * pattern. + * <p> + * The resulting log level of a scope is determined by the <em>last</em> matching term. If no term + * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log + * level of {@link Debug#DEFAULT_LOG_LEVEL}. + * + * <h2>Examples of filters</h2> + * + * <ul> + * <li>(empty string)<br> + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + * <li> {@code :1}<br> + * Matches any scope with log level 1. + * + * <li> {@code *}<br> + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + * <li> {@code CodeGen,CodeInstall}<br> + * Matches scopes containing "CodeGen" or "CodeInstall", both with log level + * {@link Debug#DEFAULT_LOG_LEVEL}. + * + * <li> {@code CodeGen:2,CodeInstall:1}<br> + * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1. + * + * <li> {@code :1,Dead:2}<br> + * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1. + * + * <li> {@code :1,Dead:0}<br> + * Matches all scopes with log level 1, except those containing "Dead". + * + * <li> {@code Code*}<br> + * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + * <li> {@code Code,~Dead}<br> + * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * </ul> + */ +final class DebugFilter { + + public static DebugFilter parse(String spec) { + if (spec == null) { + return null; + } + return new DebugFilter(spec.split(",")); + } + + private final Term[] terms; + + private DebugFilter(String[] terms) { + if (terms.length == 0) { + this.terms = null; + } else { + this.terms = new Term[terms.length]; + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + int idx = t.indexOf(':'); + + String pattern; + int level; + if (idx < 0) { + if (t.startsWith("~")) { + pattern = t.substring(1); + level = 0; + } else { + pattern = t; + level = Debug.DEFAULT_LOG_LEVEL; + } + } else { + pattern = t.substring(0, idx); + if (idx + 1 < t.length()) { + level = Integer.parseInt(t.substring(idx + 1)); + } else { + level = Debug.DEFAULT_LOG_LEVEL; + } + } + + this.terms[i] = new Term(pattern, level); + } + } + } + + /** + * Check whether a given input is matched by this filter, and determine the log level. + */ + public int matchLevel(String input) { + if (terms == null) { + return Debug.DEFAULT_LOG_LEVEL; + } else { + int level = 0; + for (Term t : terms) { + if (t.matches(input)) { + level = t.level; + } + } + return level; + } + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("DebugFilter"); + if (terms != null) { + buf.append(Arrays.toString(terms)); + } else { + buf.append("[]"); + } + return buf.toString(); + } + + private static class Term { + + private final Pattern pattern; + public final int level; + + public Term(String filter, int level) { + this.level = level; + if (filter.isEmpty()) { + this.pattern = null; + } else if (filter.contains("*") || filter.contains("?")) { + this.pattern = Pattern.compile(MethodFilter.createGlobString(filter)); + } else { + this.pattern = Pattern.compile(".*" + MethodFilter.createGlobString(filter) + ".*"); + } + } + + /** + * Determines if a given input is matched by this filter. + */ + public boolean matches(String input) { + return pattern == null || pattern.matcher(input).matches(); + } + + @Override + public String toString() { + return (pattern == null ? ".*" : pattern.toString()) + ":" + level; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.util.*; + +/** + * Facility for recording value frequencies. + */ +public interface DebugHistogram { + + /** + * Gets the name specified when this objected was {@linkplain Debug#createHistogram(String) + * created}. + */ + String getName(); + + /** + * Increments the count for a given value. + */ + void add(Object value); + + void add(Object value, long count); + + /** + * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places + * values with higher frequencies first. + */ + public class CountedValue implements Comparable<CountedValue> { + + private long count; + private final Object value; + + public CountedValue(long 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(long n) { + count += n; + } + + public long getCount() { + return count; + } + + public Object getValue() { + return value; + } + } + + /** + * Gets a list of the counted values, sorted in descending order of frequency. + */ + List<CountedValue> getValues(); + + /** + * Interface for a service that can render a visualization of a histogram. + */ + public interface Printer { + + void print(DebugHistogram histogram); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugInitializationPropertyProvider.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 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.debug; + +/** + * Sets one or more system properties used during initialization of the {@link Debug} class. + */ +public interface DebugInitializationPropertyProvider { + void apply(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import com.sun.management.*; + +/** + * Tracks memory usage within a scope using {@link ThreadMXBean}. This facility should be employed + * using the try-with-resources pattern: + * + * <pre> + * try (DebugMemUseTracker.Closeable a = memUseTracker.start()) { + * // the code to measure + * } + * </pre> + */ +public interface DebugMemUseTracker { + + /** + * Creates a point from which memory usage will be recorded if memory use tracking is + * {@linkplain Debug#isMemUseTrackingEnabled() enabled}. + * + * @return an object that must be closed once the activity has completed to add the memory used + * since this call to the total for this tracker + */ + DebugCloseable start(); + + /** + * Gets the current value of this tracker. + */ + long getCurrentValue(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMetric.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +/** + * A counter for some value of interest. + */ +public interface DebugMetric { + + /** + * Adds 1 to this counter if metering is {@link Debug#isMeterEnabled() enabled} or this is an + * {@linkplain #isConditional() unconditional} metric. + */ + void increment(); + + /** + * Adds {@code value} to this counter if metering is {@link Debug#isMeterEnabled() enabled} or + * this is an {@linkplain #isConditional() unconditional} metric. + */ + void add(long value); + + /** + * Sets a flag determining if this counter is only enabled if metering is + * {@link Debug#isMeterEnabled() enabled}. + */ + void setConditional(boolean flag); + + /** + * Determines if this counter is only enabled if metering is {@link Debug#isMeterEnabled() + * enabled}. + */ + boolean isConditional(); + + /** + * Gets the current value of this metric. + */ + long getCurrentValue(); + + /** + * Determines if this counter is enabled (either conditionally or unconditionally). + */ + default boolean isEnabled() { + return !isConditional() || Debug.isMeterEnabled(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.util.concurrent.*; + +/** + * A timer for some activity of interest. A timer should be deployed using the try-with-resources + * pattern: + * + * <pre> + * try (TimerCloseable a = timer.start()) { + * // the code to time + * } + * </pre> + */ +public interface DebugTimer { + + /** + * Starts this timer if timing is {@linkplain Debug#isTimeEnabled() enabled} or this is an + * {@linkplain #isConditional() unconditional} timer. + * + * @return an object that must be closed once the activity has completed to add the elapsed time + * since this call to the total for this timer + */ + DebugCloseable start(); + + /** + * Sets a flag determining if this timer is only enabled if timing is + * {@link Debug#isTimeEnabled() enabled}. + */ + void setConditional(boolean flag); + + /** + * Determines if this timer is only enabled if timing is {@link Debug#isTimeEnabled() enabled}. + */ + boolean isConditional(); + + /** + * Gets the current value of this timer. + */ + long getCurrentValue(); + + /** + * Gets the time unit of this timer. + */ + TimeUnit getTimeUnit(); + + /** + * Gets the timer recording the amount time spent within a timed scope minus the time spent in + * any nested timed scopes. + * + * @return null if this timer does not support flat timing + */ + default DebugTimer getFlat() { + return null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +/** + * Performs some kind of verification on an object. + */ +public interface DebugVerifyHandler { + + /** + * Verifies that a given object satisfies some invariants. + * + * @param object object to verify + * @param message description of verification context + */ + void verify(Object object, String message); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.debug.internal.*; + +public class DelegatingDebugConfig implements DebugConfig { + + protected final DebugConfig delegate; + + /** + * The features of a {@link DelegatingDebugConfig} that can be force + * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/ + * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or + * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}. + */ + public enum Feature { + /** + * @see Debug#isLogEnabledForMethod() + */ + LOG_METHOD, + /** + * @see Debug#isDumpEnabledForMethod() + */ + DUMP_METHOD, + /** + * @see Debug#isVerifyEnabled() + */ + VERIFY, + /** + * @see Debug#isVerifyEnabledForMethod() + */ + VERIFY_METHOD, + /** + * @see Debug#isMeterEnabled() + */ + METER, + /** + * @see Debug#isMemUseTrackingEnabled() + */ + TRACK_MEM_USE, + /** + * @see Debug#isTimeEnabled() + */ + TIME, + /** + * @see DebugConfig#interceptException(Throwable) + */ + INTERCEPT + } + + private final Map<Feature, Boolean> featureState = new EnumMap<>(Feature.class); + + /** + * The debug levels of a {@link DelegatingDebugConfig} than can be + * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or + * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}. + */ + public enum Level { + LOG, + DUMP + } + + private final Map<Level, Integer> levelState = new EnumMap<>(Level.class); + + /** + * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. + */ + public DelegatingDebugConfig() { + this(DebugScope.getConfig()); + } + + /** + * Creates a config that delegates to a given config. + */ + public DelegatingDebugConfig(DebugConfig delegate) { + this.delegate = delegate; + } + + public DelegatingDebugConfig enable(Feature feature) { + featureState.put(feature, Boolean.TRUE); + return this; + } + + public DelegatingDebugConfig disable(Feature feature) { + featureState.put(feature, Boolean.FALSE); + return this; + } + + public DelegatingDebugConfig override(Level level, int newLevel) { + levelState.put(level, newLevel); + return this; + } + + public DelegatingDebugConfig delegate(Feature feature) { + featureState.put(feature, null); + return this; + } + + public DelegatingDebugConfig delegate(Level level) { + levelState.put(level, null); + return this; + } + + @Override + public int getLogLevel() { + Integer ls = levelState.get(Level.LOG); + if (ls == null) { + return delegate.getLogLevel(); + } + return ls.intValue(); + } + + public boolean isLogEnabledForMethod() { + Boolean fs = featureState.get(Feature.LOG_METHOD); + if (fs == null) { + return delegate.isLogEnabledForMethod(); + } + return fs.booleanValue(); + } + + @Override + public boolean isMeterEnabled() { + Boolean fs = featureState.get(Feature.METER); + if (fs == null) { + return delegate.isMeterEnabled(); + } + return fs.booleanValue(); + } + + public boolean isMemUseTrackingEnabled() { + Boolean fs = featureState.get(Feature.TRACK_MEM_USE); + if (fs == null) { + return delegate.isMemUseTrackingEnabled(); + } + return fs.booleanValue(); + } + + @Override + public int getDumpLevel() { + Integer ls = levelState.get(Level.DUMP); + if (ls == null) { + return delegate.getDumpLevel(); + } + return ls.intValue(); + } + + public boolean isDumpEnabledForMethod() { + Boolean fs = featureState.get(Feature.DUMP_METHOD); + if (fs == null) { + return delegate.isDumpEnabledForMethod(); + } + return fs.booleanValue(); + } + + @Override + public boolean isVerifyEnabled() { + Boolean fs = featureState.get(Feature.VERIFY); + if (fs == null) { + return delegate.isVerifyEnabled(); + } + return fs.booleanValue(); + } + + public boolean isVerifyEnabledForMethod() { + Boolean fs = featureState.get(Feature.VERIFY_METHOD); + if (fs == null) { + return delegate.isVerifyEnabledForMethod(); + } + return fs.booleanValue(); + } + + @Override + public boolean isTimeEnabled() { + Boolean fs = featureState.get(Feature.TIME); + if (fs == null) { + return delegate.isTimeEnabled(); + } + return fs.booleanValue(); + } + + @Override + public RuntimeException interceptException(Throwable e) { + Boolean fs = featureState.get(Feature.INTERCEPT); + if (fs == null || fs) { + return delegate.interceptException(e); + } + return null; + } + + @Override + public Collection<DebugDumpHandler> dumpHandlers() { + return delegate.dumpHandlers(); + } + + @Override + public Collection<DebugVerifyHandler> verifyHandlers() { + return delegate.verifyHandlers(); + } + + @Override + public PrintStream output() { + return delegate.output(); + } + + @Override + public void addToContext(Object o) { + delegate.addToContext(o); + } + + @Override + public void removeFromContext(Object o) { + delegate.removeFromContext(o); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Fingerprint.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015, 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.debug; + +import java.util.*; +import java.util.stream.*; + +/** + * Facility for fingerprinting execution. + */ +public class Fingerprint implements AutoCloseable { + + public static final String ENABLED_PROPERTY_NAME = "jvmci.fingerprint"; + + /** + * Determines whether fingerprinting is enabled. This is set by the + * {@value #ENABLED_PROPERTY_NAME} system property when this class is initialized. + */ + public static final boolean ENABLED = Boolean.getBoolean(ENABLED_PROPERTY_NAME); + + private static final ThreadLocal<Fingerprint> current = ENABLED ? new ThreadLocal<>() : null; + + private final List<String> events; + private int index; + + /** + * Creates an object to record a fingerprint. + */ + public Fingerprint() { + events = new ArrayList<>(); + index = -1; + } + + /** + * Creates an object to verify execution matches a given fingerprint. + * + * @param toVerifyAgainst the fingerprint events to verify against + */ + public Fingerprint(List<String> toVerifyAgainst) { + this.events = toVerifyAgainst; + index = 0; + } + + /** + * Creates an object to verify execution matches a given fingerprint. + * + * @param toVerifyAgainst the fingerprint to verify against + */ + public Fingerprint(Fingerprint toVerifyAgainst) { + this(toVerifyAgainst.events); + } + + public Collection<String> getEvents() { + return Collections.unmodifiableCollection(events); + } + + /** + * Starts fingerprint recording or verification for the current thread. At most one fingerprint + * object can be active for any thread. + */ + public Fingerprint open() { + if (ENABLED) { + assert current.get() == null; + current.set(this); + return this; + } + return null; + } + + /** + * Finishes fingerprint recording or verification for the current thread. + */ + public void close() { + if (ENABLED) { + assert current.get() == this; + current.set(null); + } + } + + private static final int BREAKPOINT_EVENT = Integer.getInteger(ENABLED_PROPERTY_NAME + ".breakpointEvent", -1); + + /** + * Submits an execution event for the purpose of recording or verifying a fingerprint. This must + * only be called if {@link #ENABLED} is {@code true}. + */ + public static void submit(String format, Object... args) { + assert ENABLED : "fingerprinting must be enabled (-D" + ENABLED_PROPERTY_NAME + "=true)"; + Fingerprint fingerprint = current.get(); + if (fingerprint != null) { + int eventId = fingerprint.nextEventId(); + if (eventId == BREAKPOINT_EVENT) { + // Set IDE breakpoint on the following line and set the relevant + // system property to debug a fingerprint verification error. + System.console(); + } + fingerprint.event(String.format(eventId + ": " + format, args)); + } + } + + private int nextEventId() { + return index == -1 ? events.size() : index; + } + + private static final int MAX_EVENT_TAIL_IN_ERROR_MESSAGE = Integer.getInteger("jvmci.fingerprint.errorEventTailLength", 50); + + private String tail() { + int start = Math.max(index - MAX_EVENT_TAIL_IN_ERROR_MESSAGE, 0); + return events.subList(start, index).stream().collect(Collectors.joining(String.format("%n"))); + } + + private void event(String entry) { + if (index == -1) { + events.add(entry); + } else { + if (index > events.size()) { + throw new InternalError(String.format("%s%nOriginal fingerprint limit reached", tail())); + } + String l = events.get(index); + if (!l.equals(entry)) { + throw new InternalError(String.format("%s%nFingerprint differs at event %d%nexpected: %s%n actual: %s", tail(), index, l, entry)); + } + index++; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +/** + * Object used to close a debug {@link Debug#indent() indentation} scope. + * <p> + * Example usage: + * + * <pre> + * + * try (Indent i1 = Debug.logAndIndent("header message")) { + * ... + * Debug.log("message"); + * ... + * try (Indent i2 = Debug.logAndIndent(sub-header message")) { + * ... + * Debug.log("inner message"); + * ... + * } + * } + * + * </pre> + */ +public interface Indent extends AutoCloseable { + + /** + * Closes the current indentation scope. + */ + void close(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/JVMCIDebugConfig.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.io.*; +import java.util.*; + +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.options.*; + +public class JVMCIDebugConfig implements DebugConfig { + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + return assertionsEnabled; + } + + // @formatter:off + @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) + public static final OptionValue<String> Dump = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all metrics unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Meter = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) + public static final OptionValue<String> Verify = new OptionValue<String>() { + @Override + protected String defaultValue() { + return assertionsEnabled() ? "" : null; + } + }; + @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> TrackMemUse = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + + "An empty value enables all timers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Time = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) + public static final OptionValue<String> Log = new OptionValue<>(null); + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) + public static final OptionValue<String> MethodFilter = new OptionValue<>(null); + @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) + public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false); + + @Option(help = "How to print metric and timing values:%n" + + "Name - aggregate by unqualified name%n" + + "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + + "Complete - aggregate by qualified name%n" + + "Thread - aggregate by qualified name and thread", type = OptionType.Debug) + public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) + public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); + @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) + public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null); + @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug) + public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); + @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) + public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false); + @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) + public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false); + // @formatter:on + + static boolean isNotEmpty(OptionValue<String> option) { + return option.getValue() != null && !option.getValue().isEmpty(); + } + + public static boolean areDebugScopePatternsEnabled() { + return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); + } + + /** + * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, + * non-empty value. + */ + public static boolean areScopedMetricsOrTimersEnabled() { + return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); + } + + private final DebugFilter logFilter; + private final DebugFilter meterFilter; + private final DebugFilter trackMemUseFilter; + private final DebugFilter timerFilter; + private final DebugFilter dumpFilter; + private final DebugFilter verifyFilter; + private final MethodFilter[] methodFilter; + private final List<DebugDumpHandler> dumpHandlers; + private final List<DebugVerifyHandler> verifyHandlers; + private final PrintStream output; + private final Set<Object> extraFilters = new HashSet<>(); + + public JVMCIDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, + List<DebugDumpHandler> dumpHandlers, List<DebugVerifyHandler> verifyHandlers) { + this.logFilter = DebugFilter.parse(logFilter); + this.meterFilter = DebugFilter.parse(meterFilter); + this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); + this.timerFilter = DebugFilter.parse(timerFilter); + this.dumpFilter = DebugFilter.parse(dumpFilter); + this.verifyFilter = DebugFilter.parse(verifyFilter); + if (methodFilter == null || methodFilter.isEmpty()) { + this.methodFilter = null; + } else { + this.methodFilter = com.oracle.graal.debug.MethodFilter.parse(methodFilter); + } + + // Report the filters that have been configured so the user can verify it's what they expect + if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) { + // TTY.println(Thread.currentThread().getName() + ": " + toString()); + } + this.dumpHandlers = dumpHandlers; + this.verifyHandlers = verifyHandlers; + this.output = output; + } + + public int getLogLevel() { + return getLevel(logFilter); + } + + public boolean isLogEnabledForMethod() { + return isEnabledForMethod(logFilter); + } + + public boolean isMeterEnabled() { + return isEnabled(meterFilter); + } + + public boolean isMemUseTrackingEnabled() { + return isEnabled(trackMemUseFilter); + } + + public int getDumpLevel() { + return getLevel(dumpFilter); + } + + public boolean isDumpEnabledForMethod() { + return isEnabledForMethod(dumpFilter); + } + + public boolean isVerifyEnabled() { + return isEnabled(verifyFilter); + } + + public boolean isVerifyEnabledForMethod() { + return isEnabledForMethod(verifyFilter); + } + + public boolean isTimeEnabled() { + return isEnabled(timerFilter); + } + + public PrintStream output() { + return output; + } + + private boolean isEnabled(DebugFilter filter) { + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level; + if (filter == null) { + level = 0; + } else { + level = filter.matchLevel(Debug.currentScope()); + } + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; + } + + private boolean isEnabledForMethod(DebugFilter filter) { + return filter != null && checkMethodFilter(); + } + + /** + * Extracts a {@link JavaMethod} from an opaque debug context. + * + * @return the {@link JavaMethod} represented by {@code context} or null + */ + public static JavaMethod asJavaMethod(Object context) { + if (context instanceof JavaMethodContex) { + return ((JavaMethodContex) context).asJavaMethod(); + } + return null; + } + + private boolean checkMethodFilter() { + if (methodFilter == null && extraFilters.isEmpty()) { + return true; + } else { + JavaMethod lastMethod = null; + for (Object o : Debug.context()) { + if (extraFilters.contains(o)) { + return true; + } else if (methodFilter != null) { + JavaMethod method = asJavaMethod(o); + if (method != null) { + if (!MethodFilterRootOnly.getValue()) { + if (com.oracle.graal.debug.MethodFilter.matches(methodFilter, method)) { + return true; + } + } else { + /* + * The context values operate as a stack so if we want MethodFilter to + * only apply to the root method we have to check only the last method + * seen. + */ + lastMethod = method; + } + } + } + } + if (lastMethod != null && com.oracle.graal.debug.MethodFilter.matches(methodFilter, lastMethod)) { + return true; + } + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Debug config:"); + add(sb, "Log", logFilter); + add(sb, "Meter", meterFilter); + add(sb, "Time", timerFilter); + add(sb, "Dump", dumpFilter); + add(sb, "MethodFilter", methodFilter); + return sb.toString(); + } + + private static void add(StringBuilder sb, String name, Object filter) { + if (filter != null) { + sb.append(' '); + sb.append(name); + sb.append('='); + if (filter instanceof Object[]) { + sb.append(Arrays.toString((Object[]) filter)); + } else { + sb.append(String.valueOf(filter)); + } + } + } + + @Override + public RuntimeException interceptException(Throwable e) { + if (e instanceof BailoutException && !InterceptBailout.getValue()) { + return null; + } + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); + for (Object o : Debug.context()) { + if (DumpOnError.getValue()) { + Debug.dump(o, "Exception: " + e.toString()); + } else { + Debug.log("Context obj %s", o); + } + + } + return null; + } + + @Override + public Collection<DebugDumpHandler> dumpHandlers() { + return dumpHandlers; + } + + @Override + public Collection<DebugVerifyHandler> verifyHandlers() { + return verifyHandlers; + } + + @Override + public void addToContext(Object o) { + extraFilters.add(o); + } + + @Override + public void removeFromContext(Object o) { + extraFilters.remove(o); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/JavaMethodContex.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, 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.debug; + +import jdk.internal.jvmci.meta.*; + +/** + * Interface for objects used in Debug {@linkplain Debug#context() context} that can provide a + * {@link JavaMethod}. + */ +public interface JavaMethodContex { + JavaMethod asJavaMethod(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/MethodFilter.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.util.*; +import java.util.regex.*; + +import jdk.internal.jvmci.meta.*; + +/** + * This class implements a method filter that can filter based on class name, method name and + * parameters. The syntax for the source pattern that is passed to the constructor is as follows: + * + * <pre> + * SourcePatterns = SourcePattern ["," SourcePatterns] . + * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] . + * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" . + * Class = { package "." } class . + * </pre> + * + * + * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid + * filters are: + * + * <ul> + * <li> + * + * <pre> + * visit(Argument;BlockScope) + * </pre> + * + * Matches all methods named "visit", with the first parameter of type "Argument", and the second + * parameter of type "BlockScope". The packages of the parameter types are irrelevant.</li> + * <li> + * + * <pre> + * arraycopy(Object;;;;) + * </pre> + * + * Matches all methods named "arraycopy", with the first parameter of type "Object", and four more + * parameters of any type. The packages of the parameter types are irrelevant.</li> + * <li> + * + * <pre> + * com.oracle.graal.compiler.graph.PostOrderNodeIterator.* + * </pre> + * + * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".</li> + * <li> + * + * <pre> + * * + * </pre> + * + * Matches all methods in all classes</li> + * <li> + * + * <pre> + * com.oracle.graal.compiler.graph.*.visit + * </pre> + * + * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph". + * <li> + * + * <pre> + * arraycopy,toString + * </pre> + * + * Matches all methods named "arraycopy" or "toString", meaning that ',' acts as an <i>or</i> + * operator.</li> + * </ul> + */ +public class MethodFilter { + + private final Pattern clazz; + private final Pattern methodName; + private final Pattern[] signature; + + /** + * Parses a string containing list of comma separated filter patterns into an array of + * {@link MethodFilter}s. + */ + public static MethodFilter[] parse(String commaSeparatedPatterns) { + String[] filters = commaSeparatedPatterns.split(","); + MethodFilter[] methodFilters = new MethodFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + methodFilters[i] = new MethodFilter(filters[i]); + } + return methodFilters; + } + + /** + * Determines if a given method is matched by a given array of filters. + */ + public static boolean matches(MethodFilter[] filters, JavaMethod method) { + for (MethodFilter filter : filters) { + if (filter.matches(method)) { + return true; + } + } + return false; + } + + /** + * Determines if a given class name is matched by a given array of filters. + */ + public static boolean matchesClassName(MethodFilter[] filters, String className) { + for (MethodFilter filter : filters) { + if (filter.matchesClassName(className)) { + return true; + } + } + return false; + } + + public MethodFilter(String sourcePattern) { + String pattern = sourcePattern.trim(); + + // extract parameter part + int pos = pattern.indexOf('('); + if (pos != -1) { + if (pattern.charAt(pattern.length() - 1) != ')') { + throw new IllegalArgumentException("missing ')' at end of method filter pattern: " + pattern); + } + String[] signatureClasses = pattern.substring(pos + 1, pattern.length() - 1).split(";", -1); + signature = new Pattern[signatureClasses.length]; + for (int i = 0; i < signatureClasses.length; i++) { + signature[i] = createClassGlobPattern(signatureClasses[i].trim()); + } + pattern = pattern.substring(0, pos); + } else { + signature = null; + } + + // If there is at least one "." then everything before the last "." is the class name. + // Otherwise, the pattern contains only the method name. + pos = pattern.lastIndexOf('.'); + if (pos != -1) { + clazz = createClassGlobPattern(pattern.substring(0, pos)); + methodName = Pattern.compile(createGlobString(pattern.substring(pos + 1))); + } else { + clazz = null; + methodName = Pattern.compile(createGlobString(pattern)); + } + } + + public static String createGlobString(String pattern) { + return Pattern.quote(pattern).replace("?", "\\E.\\Q").replace("*", "\\E.*\\Q"); + } + + private static Pattern createClassGlobPattern(String pattern) { + if (pattern.length() == 0) { + return null; + } else if (pattern.contains(".")) { + return Pattern.compile(createGlobString(pattern)); + } else { + return Pattern.compile("([^\\.\\$]*[\\.\\$])*" + createGlobString(pattern)); + } + } + + /** + * Determines if the class part of this filter matches a given class name. + */ + public boolean matchesClassName(String className) { + return clazz == null || clazz.matcher(className).matches(); + } + + public boolean matches(JavaMethod o) { + // check method name first, since MetaUtil.toJavaName is expensive + if (methodName != null && !methodName.matcher(o.getName()).matches()) { + return false; + } + if (clazz != null && !clazz.matcher(o.getDeclaringClass().toJavaName()).matches()) { + return false; + } + if (signature != null) { + Signature sig = o.getSignature(); + if (sig.getParameterCount(false) != signature.length) { + return false; + } + for (int i = 0; i < signature.length; i++) { + JavaType type = sig.getParameterType(i, null); + String javaName = type.toJavaName(); + if (signature[i] != null && !signature[i].matcher(javaName).matches()) { + return false; + } + } + } + return true; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("MethodFilter["); + String sep = ""; + if (clazz != null) { + buf.append(sep).append("clazz=").append(clazz); + sep = ", "; + } + if (methodName != null) { + buf.append(sep).append("methodName=").append(methodName); + sep = ", "; + } + if (signature != null) { + buf.append(sep).append("signature=").append(Arrays.toString(signature)); + sep = ", "; + } + return buf.append("]").toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TopLevelDebugConfig.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 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.debug; + +/** + * A marker class for a scoped debug configuration covering a compilation region. Useful for + * programmatically enabling debug config features. + * + */ +public class TopLevelDebugConfig extends DelegatingDebugConfig { +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/AccumulatedDebugValue.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, 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.debug.internal; + +public abstract class AccumulatedDebugValue extends DebugValue { + protected final DebugValue flat; + + public AccumulatedDebugValue(String name, boolean conditional, DebugValue flat) { + super(name + "_Accm", conditional); + this.flat = flat; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/CloseableCounterImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015, 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.debug.internal; + +import com.oracle.graal.debug.*; + +/** + * A helper class for DebugValues that can nest and need to split out accumulated and flat values + * for some kind of counter-like measurement. + */ +abstract class CloseableCounterImpl implements DebugCloseable { + + protected final CloseableCounterImpl parent; + protected final AccumulatedDebugValue counter; + protected final long start; + protected long nestedAmountToSubtract; + + CloseableCounterImpl(CloseableCounterImpl parent, AccumulatedDebugValue counter) { + this.parent = parent; + this.start = getCounterValue(); + this.counter = counter; + } + + @Override + public void close() { + long end = getCounterValue(); + long difference = end - start; + if (parent != null) { + if (!counter.getName().equals(parent.counter.getName())) { + parent.nestedAmountToSubtract += difference; + + // Look for our counter in an outer scope and fix up + // the adjustment to the flat count + CloseableCounterImpl ancestor = parent.parent; + while (ancestor != null) { + if (ancestor.counter.getName().equals(counter.getName())) { + ancestor.nestedAmountToSubtract -= difference; + break; + } + ancestor = ancestor.parent; + } + } + } + long flatAmount = difference - nestedAmountToSubtract; + counter.addToCurrentValue(difference); + counter.flat.addToCurrentValue(flatAmount); + } + + abstract long getCounterValue(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.DebugHistogram.*; + +/** + * Renders a textual representation of a histogram to a given print stream. + */ +public class DebugHistogramAsciiPrinter implements Printer { + + public static final int NumberSize = 10; + public static final int DefaultNameSize = 50; + public static final int DefaultBarSize = 100; + public static final int DefaultScale = 1; + + private final PrintStream os; + private final int limit; + private final int nameSize; + private final int barSize; + private final int scale; + + public DebugHistogramAsciiPrinter(PrintStream os) { + this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize, DefaultScale); + } + + /** + * @param os where to print + * @param limit limits printing to the {@code limit} most frequent values + * @param nameSize the width of the value names column + * @param barSize the width of the value frequency column + * @param scale a factor by which every result is divided + */ + public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize, int scale) { + this.os = os; + this.limit = limit; + this.nameSize = nameSize; + this.barSize = barSize; + this.scale = scale; + } + + public void print(DebugHistogram histogram) { + List<CountedValue> list = histogram.getValues(); + if (list.isEmpty()) { + os.printf("%s is empty.%n", histogram.getName()); + return; + } + + // Sum up the total number of elements. + long total = list.stream().mapToLong(CountedValue::getCount).sum(); + + // Print header. + os.printf("%s has %d unique elements and %d total elements:%n", histogram.getName(), list.size(), total / scale); + + long max = list.get(0).getCount() / scale; + final int lineSize = nameSize + NumberSize + barSize + 10; + printLine(os, '-', 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); + long value = cv.getCount() / scale; + char[] bar = new char[(int) (((double) value / (double) max) * barSize)]; + Arrays.fill(bar, '='); + String objectString = String.valueOf(cv.getValue()); + if (objectString.length() > nameSize) { + objectString = objectString.substring(0, nameSize - 3) + "..."; + } + os.printf(formatString, objectString, value, new String(bar)); + } + printLine(os, '-', lineSize); + } + + 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)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.util.*; + +import com.oracle.graal.debug.*; + +public class DebugHistogramImpl implements DebugHistogram { + + private final String name; + private HashMap<Object, CountedValue> map = new HashMap<>(); + + public DebugHistogramImpl(String name) { + this.name = name; + } + + public void add(Object value) { + CountedValue cv = map.get(value); + if (cv == null) { + map.put(value, new CountedValue(1, value)); + } else { + cv.inc(); + } + } + + public void add(Object value, long count) { + CountedValue cv = map.get(value); + if (cv == null) { + map.put(value, new CountedValue(count, value)); + } else { + cv.add(count); + } + } + + @Override + public String getName() { + return name; + } + + public List<CountedValue> getValues() { + ArrayList<CountedValue> res = new ArrayList<>(map.values()); + Collections.sort(res); + return res; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramRPrinter.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.DebugHistogram.*; + +/** + * Renders a histogram as an R script to a given print stream. The R script emitted for a histogram + * is a simple set of statements for defining a vector of named objects. + */ +public class DebugHistogramRPrinter implements Printer { + + private PrintStream os; + private int limit; + + public DebugHistogramRPrinter(PrintStream os) { + this(os, Integer.MAX_VALUE); + } + + /** + * @param os where to print + * @param limit limits printing to the {@code limit} most frequent values + */ + public DebugHistogramRPrinter(PrintStream os, int limit) { + this.os = os; + this.limit = limit; + } + + public void print(DebugHistogram histogram) { + List<CountedValue> list = histogram.getValues(); + if (list.isEmpty()) { + return; + } + + String var = histogram.getName().replace('-', '.').replace(' ', '_'); + os.print(var + " <- c("); + for (int i = 0; i < list.size() && i < limit; ++i) { + CountedValue cv = list.get(i); + if (i != 0) { + os.print(", "); + } + os.print(cv.getCount()); + } + os.println(");"); + + os.print("names(" + var + ") <- c("); + for (int i = 0; i < list.size() && i < limit; ++i) { + CountedValue cv = list.get(i); + if (i != 0) { + os.print(", "); + } + os.print("\"" + cv.getValue() + "\""); + } + os.println(");"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.io.*; +import java.util.*; +import java.util.concurrent.*; + +import jdk.internal.jvmci.debug.*; + +import com.oracle.graal.debug.*; + +public final class DebugScope implements Debug.Scope { + + private final class IndentImpl implements Indent { + + private static final String INDENTATION_INCREMENT = " "; + + final String indent; + final IndentImpl parentIndent; + + IndentImpl(IndentImpl parentIndent) { + this.parentIndent = parentIndent; + this.indent = (parentIndent == null ? "" : parentIndent.indent + INDENTATION_INCREMENT); + } + + private void printScopeName(StringBuilder str) { + if (logScopeName) { + if (parentIndent != null) { + parentIndent.printScopeName(str); + } + str.append(indent).append("[thread:").append(Thread.currentThread().getId()).append("] scope: ").append(getQualifiedName()).append(System.lineSeparator()); + logScopeName = false; + } + } + + public void log(int logLevel, String msg, Object... args) { + if (isLogEnabled(logLevel)) { + StringBuilder str = new StringBuilder(); + printScopeName(str); + str.append(indent); + String result = args.length == 0 ? msg : String.format(msg, args); + String lineSep = System.lineSeparator(); + str.append(result.replace(lineSep, lineSep.concat(indent))); + str.append(lineSep); + output.append(str); + lastUsedIndent = this; + } + } + + IndentImpl indent() { + lastUsedIndent = new IndentImpl(this); + return lastUsedIndent; + } + + @Override + public void close() { + if (parentIndent != null) { + lastUsedIndent = parentIndent; + } + } + } + + private static final ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>(); + private static final ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>(); + private static final ThreadLocal<DebugConfig> configTL = new ThreadLocal<>(); + private static final ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>(); + + private final DebugScope parent; + private final DebugConfig parentConfig; + private final boolean sandbox; + private IndentImpl lastUsedIndent; + private boolean logScopeName; + + private final Object[] context; + + private DebugValueMap valueMap; + + private String qualifiedName; + private final String unqualifiedName; + + private static final char SCOPE_SEP = '.'; + + private boolean meterEnabled; + private boolean timeEnabled; + private boolean memUseTrackingEnabled; + private boolean verifyEnabled; + + private int currentDumpLevel; + private int currentLogLevel; + + private PrintStream output; + + public static DebugScope getInstance() { + DebugScope result = instanceTL.get(); + if (result == null) { + DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread()); + instanceTL.set(topLevelDebugScope); + return topLevelDebugScope; + } else { + return result; + } + } + + public static DebugConfig getConfig() { + return configTL.get(); + } + + static final Object[] EMPTY_CONTEXT = new Object[0]; + + private DebugScope(Thread thread) { + this(thread.getName(), null, false); + computeValueMap(thread.getName()); + DebugValueMap.registerTopLevel(getValueMap()); + } + + private DebugScope(String unqualifiedName, DebugScope parent, boolean sandbox, Object... context) { + this.parent = parent; + this.sandbox = sandbox; + this.parentConfig = getConfig(); + this.context = context; + this.unqualifiedName = unqualifiedName; + if (parent != null) { + logScopeName = !unqualifiedName.equals(""); + } else { + logScopeName = true; + } + + this.output = TTY.out; + assert context != null; + } + + private void computeValueMap(String name) { + if (parent != null) { + for (DebugValueMap child : parent.getValueMap().getChildren()) { + if (child.getName().equals(name)) { + this.valueMap = child; + return; + } + } + this.valueMap = new DebugValueMap(name); + parent.getValueMap().addChild(this.valueMap); + } else { + this.valueMap = new DebugValueMap(name); + } + } + + public void close() { + instanceTL.set(parent); + configTL.set(parentConfig); + lastClosedTL.set(this); + } + + public boolean isDumpEnabled(int dumpLevel) { + assert dumpLevel > 0; + return currentDumpLevel >= dumpLevel; + } + + /** + * Enable dumping at the new {@code dumpLevel} for the remainder of enclosing scopes. This only + * works if a {@link TopLevelDebugConfig} was installed at a higher scope. + * + * @param dumpLevel + */ + public static void setDumpLevel(int dumpLevel) { + TopLevelDebugConfig config = fetchTopLevelDebugConfig("setDebugLevel"); + if (config != null) { + config.override(DelegatingDebugConfig.Level.DUMP, dumpLevel); + recursiveUpdateFlags(); + } + } + + /** + * Enable logging at the new {@code logLevel} for the remainder of enclosing scopes. This only + * works if a {@link TopLevelDebugConfig} was installed at a higher scope. + * + * @param logLevel + */ + public static void setLogLevel(int logLevel) { + TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel"); + if (config != null) { + config.override(DelegatingDebugConfig.Level.LOG, logLevel); + config.delegate(DelegatingDebugConfig.Feature.LOG_METHOD); + recursiveUpdateFlags(); + } + } + + private static void recursiveUpdateFlags() { + DebugScope c = DebugScope.getInstance(); + while (c != null) { + c.updateFlags(); + c = c.parent; + } + } + + private static TopLevelDebugConfig fetchTopLevelDebugConfig(String msg) { + DebugConfig config = getConfig(); + if (config instanceof TopLevelDebugConfig) { + return (TopLevelDebugConfig) config; + } else { + if (config == null) { + TTY.println("DebugScope.%s ignored because debugging is disabled", msg); + } else { + TTY.println("DebugScope.%s ignored because top level delegate config missing", msg); + } + return null; + } + } + + public boolean isVerifyEnabled() { + return verifyEnabled; + } + + public boolean isLogEnabled(int logLevel) { + assert logLevel > 0; + return currentLogLevel >= logLevel; + } + + public boolean isMeterEnabled() { + return meterEnabled; + } + + public boolean isTimeEnabled() { + return timeEnabled; + } + + public boolean isMemUseTrackingEnabled() { + return memUseTrackingEnabled; + } + + public void log(int logLevel, String msg, Object... args) { + if (isLogEnabled(logLevel)) { + getLastUsedIndent().log(logLevel, msg, args); + } + } + + public void dump(int dumpLevel, Object object, String formatString, Object... args) { + if (isDumpEnabled(dumpLevel)) { + DebugConfig config = getConfig(); + if (config != null) { + String message = String.format(formatString, args); + for (DebugDumpHandler dumpHandler : config.dumpHandlers()) { + dumpHandler.dump(object, message); + } + } + } + } + + /** + * This method exists mainly to allow a debugger (e.g., Eclipse) to force dump a graph. + */ + public static void forceDump(Object object, String format, Object... args) { + DebugConfig config = getConfig(); + if (config != null) { + String message = String.format(format, args); + for (DebugDumpHandler dumpHandler : config.dumpHandlers()) { + dumpHandler.dump(object, message); + } + } else { + TTY.println("Forced dump ignored because debugging is disabled - use -G:Dump=xxx option"); + } + } + + /** + * @see Debug#verify(Object, String) + */ + public void verify(Object object, String formatString, Object... args) { + if (isVerifyEnabled()) { + DebugConfig config = getConfig(); + if (config != null) { + String message = String.format(formatString, args); + for (DebugVerifyHandler handler : config.verifyHandlers()) { + handler.verify(object, message); + } + } + } + } + + /** + * Creates and enters a new debug scope which is either a child of the current scope or a + * disjoint top level scope. + * + * @param name the name of the new scope + * @param sandboxConfig the configuration to use for a new top level scope, or null if the new + * scope should be a child scope + * @param newContextObjects objects to be appended to the debug context + * @return the new scope which will be exited when its {@link #close()} method is called + */ + public DebugScope scope(CharSequence name, DebugConfig sandboxConfig, Object... newContextObjects) { + DebugScope newScope = null; + if (sandboxConfig != null) { + newScope = new DebugScope(name.toString(), this, true, newContextObjects); + configTL.set(sandboxConfig); + } else { + newScope = this.createChild(name.toString(), newContextObjects); + } + instanceTL.set(newScope); + newScope.updateFlags(); + return newScope; + } + + public RuntimeException handle(Throwable e) { + DebugScope lastClosed = lastClosedTL.get(); + assert lastClosed.parent == this : "Debug.handle() used with no matching Debug.scope(...) or Debug.sandbox(...)"; + if (e != lastExceptionThrownTL.get()) { + RuntimeException newException = null; + instanceTL.set(lastClosed); + try (DebugScope s = lastClosed) { + newException = s.interceptException(e); + } + assert instanceTL.get() == this; + assert lastClosed == lastClosedTL.get(); + if (newException == null) { + lastExceptionThrownTL.set(e); + } else { + lastExceptionThrownTL.set(newException); + throw newException; + } + } + if (e instanceof Error) { + throw (Error) e; + } + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw new RuntimeException(e); + } + + private void updateFlags() { + DebugConfig config = getConfig(); + if (config == null) { + meterEnabled = false; + memUseTrackingEnabled = false; + timeEnabled = false; + verifyEnabled = false; + + currentDumpLevel = 0; + + // Be pragmatic: provide a default log stream to prevent a crash if the stream is not + // set while logging + output = TTY.out; + } else { + meterEnabled = config.isMeterEnabled(); + memUseTrackingEnabled = config.isMemUseTrackingEnabled(); + timeEnabled = config.isTimeEnabled(); + verifyEnabled = config.isVerifyEnabled(); + output = config.output(); + currentDumpLevel = config.getDumpLevel(); + currentLogLevel = config.getLogLevel(); + } + } + + private RuntimeException interceptException(final Throwable e) { + final DebugConfig config = getConfig(); + if (config != null) { + try (DebugScope s = scope("InterceptException", null, e)) { + return config.interceptException(e); + } catch (Throwable t) { + return new RuntimeException("Exception while intercepting exception", t); + } + } + return null; + } + + private DebugValueMap getValueMap() { + if (valueMap == null) { + computeValueMap(unqualifiedName); + } + return valueMap; + } + + long getCurrentValue(int index) { + return getValueMap().getCurrentValue(index); + } + + void setCurrentValue(int index, long l) { + getValueMap().setCurrentValue(index, l); + } + + private DebugScope createChild(String newName, Object[] newContext) { + return new DebugScope(newName, this, false, newContext); + } + + public Iterable<Object> getCurrentContext() { + final DebugScope scope = this; + return new Iterable<Object>() { + + @Override + public Iterator<Object> iterator() { + return new Iterator<Object>() { + + DebugScope currentScope = scope; + int objectIndex; + + @Override + public boolean hasNext() { + selectScope(); + return currentScope != null; + } + + private void selectScope() { + while (currentScope != null && currentScope.context.length <= objectIndex) { + currentScope = currentScope.sandbox ? null : currentScope.parent; + objectIndex = 0; + } + } + + @Override + public Object next() { + selectScope(); + if (currentScope != null) { + return currentScope.context[objectIndex++]; + } + throw new IllegalStateException("May only be called if there is a next element."); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("This iterator is read only."); + } + }; + } + }; + } + + public static <T> T call(Callable<T> callable) { + try { + return callable.call(); + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException(e); + } + } + } + + public void setConfig(DebugConfig newConfig) { + configTL.set(newConfig); + updateFlags(); + } + + public String getQualifiedName() { + if (qualifiedName == null) { + if (parent == null) { + qualifiedName = unqualifiedName; + } else { + qualifiedName = parent.getQualifiedName() + SCOPE_SEP + unqualifiedName; + } + } + return qualifiedName; + } + + public Indent pushIndentLogger() { + lastUsedIndent = getLastUsedIndent().indent(); + return lastUsedIndent; + } + + public IndentImpl getLastUsedIndent() { + if (lastUsedIndent == null) { + if (parent != null) { + lastUsedIndent = new IndentImpl(parent.getLastUsedIndent()); + } else { + lastUsedIndent = new IndentImpl(null); + } + } + return lastUsedIndent; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +/** + * A name and index for a value managed in a thread local value map. All access to the value is made + * via a {@link DebugValue} instance. + */ +public abstract class DebugValue implements Comparable<DebugValue> { + + private final String name; + private int index; + private boolean conditional; + + protected DebugValue(String name, boolean conditional) { + this.name = name; + this.index = -1; + this.conditional = conditional; + } + + public long getCurrentValue() { + ensureInitialized(); + return DebugScope.getInstance().getCurrentValue(index); + } + + protected void setCurrentValue(long l) { + ensureInitialized(); + DebugScope.getInstance().setCurrentValue(index, l); + } + + public void setConditional(boolean flag) { + conditional = flag; + } + + public boolean isConditional() { + return conditional; + } + + private void ensureInitialized() { + if (index == -1) { + index = KeyRegistry.register(this); + } + } + + protected void addToCurrentValue(long value) { + setCurrentValue(getCurrentValue() + value); + } + + /** + * Gets the globally unique index for the value represented by this object. + */ + public int getIndex() { + ensureInitialized(); + return index; + } + + /** + * Gets the globally unique name for the value represented by this object. + */ + public String getName() { + return name; + } + + public int compareTo(DebugValue o) { + return name.compareTo(o.name); + } + + @Override + public String toString() { + return name + "@" + index; + } + + public abstract String toString(long value); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValueMap.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.util.*; + +/** + * A node in a tree of {@link DebugValue}s. + */ +public class DebugValueMap { + + private static final List<DebugValueMap> topLevelMaps = new ArrayList<>(); + + private long[] values; + private List<DebugValueMap> children; + private String name; + + public DebugValueMap(String name) { + this.name = name; + } + + public void setCurrentValue(int index, long l) { + ensureSize(index); + values[index] = l; + } + + public long getCurrentValue(int index) { + ensureSize(index); + return values[index]; + } + + public void clearChildren() { + if (children != null) { + children.clear(); + } + } + + public void reset() { + if (values != null) { + Arrays.fill(values, 0L); + } + if (children != null) { + for (DebugValueMap child : children) { + child.reset(); + } + } + } + + private void ensureSize(int index) { + if (values == null) { + values = new long[index + 1]; + } + if (values.length <= index) { + values = Arrays.copyOf(values, index + 1); + } + } + + private int capacity() { + return (values == null) ? 0 : values.length; + } + + public void addChild(DebugValueMap map) { + if (children == null) { + children = new ArrayList<>(4); + } + children.add(map); + } + + public List<DebugValueMap> getChildren() { + if (children == null) { + return Collections.emptyList(); + } else { + return Collections.unmodifiableList(children); + } + } + + public boolean hasChildren() { + return children != null && !children.isEmpty(); + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return "DebugValueMap<" + getName() + ">"; + } + + public static synchronized void registerTopLevel(DebugValueMap map) { + topLevelMaps.add(map); + } + + public static synchronized List<DebugValueMap> getTopLevelMaps() { + return topLevelMaps; + } + + public void normalize() { + if (hasChildren()) { + Map<String, DebugValueMap> occurred = new HashMap<>(); + for (DebugValueMap map : children) { + String mapName = map.getName(); + if (!occurred.containsKey(mapName)) { + occurred.put(mapName, map); + map.normalize(); + } else { + occurred.get(mapName).mergeWith(map); + occurred.get(mapName).normalize(); + } + } + + if (occurred.values().size() < children.size()) { + // At least one duplicate was found. + children.clear(); + for (DebugValueMap map : occurred.values()) { + addChild(map); + map.normalize(); + } + } + } + } + + private void mergeWith(DebugValueMap map) { + if (map.hasChildren()) { + if (hasChildren()) { + children.addAll(map.children); + } else { + children = map.children; + } + map.children = null; + } + + int size = Math.max(this.capacity(), map.capacity()); + ensureSize(size); + for (int i = 0; i < size; ++i) { + long curValue = getCurrentValue(i); + long otherValue = map.getCurrentValue(i); + setCurrentValue(i, curValue + otherValue); + } + } + + public void group() { + if (this.hasChildren()) { + List<DebugValueMap> oldChildren = new ArrayList<>(this.children); + this.children.clear(); + for (DebugValueMap map : oldChildren) { + mergeWith(map); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/KeyRegistry.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import java.util.*; + +/** + * Registry for allocating a globally unique integer id to each {@link DebugValue}. + */ +public class KeyRegistry { + + private static final Map<String, Integer> keyMap = new HashMap<>(); + private static final List<DebugValue> debugValues = new ArrayList<>(); + + /** + * Ensures a given debug value is registered. + * + * @return the globally unique id for {@code value} + */ + public static synchronized int register(DebugValue value) { + String name = value.getName(); + if (!keyMap.containsKey(name)) { + keyMap.put(name, debugValues.size()); + debugValues.add(value); + } + return keyMap.get(name); + } + + /** + * Gets a immutable view of the registered debug values. + * + * @return a list where {@code get(i).getIndex() == i} + */ + public static synchronized List<DebugValue> getDebugValues() { + return Collections.unmodifiableList(debugValues); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import static com.oracle.graal.debug.DebugCloseable.*; +import jdk.internal.jvmci.debug.*; + +import com.oracle.graal.debug.*; + +public final class MemUseTrackerImpl extends AccumulatedDebugValue implements DebugMemUseTracker { + + public static long getCurrentThreadAllocatedBytes() { + return Management.getCurrentThreadAllocatedBytes(); + } + + /** + * Records the most recent active tracker. + */ + private static final ThreadLocal<CloseableCounterImpl> currentTracker = new ThreadLocal<>(); + + public MemUseTrackerImpl(String name, boolean conditional) { + super(name, conditional, new DebugValue(name + "_Flat", conditional) { + + @Override + public String toString(long value) { + return valueToString(value); + } + }); + } + + @Override + public DebugCloseable start() { + if (!isConditional() || Debug.isMemUseTrackingEnabled()) { + MemUseCloseableCounterImpl result = new MemUseCloseableCounterImpl(this); + currentTracker.set(result); + return result; + } else { + return VOID_CLOSEABLE; + } + } + + public static String valueToString(long value) { + return String.format("%d bytes", value); + } + + @Override + public String toString(long value) { + return valueToString(value); + } + + private static final class MemUseCloseableCounterImpl extends CloseableCounterImpl implements DebugCloseable { + + private MemUseCloseableCounterImpl(AccumulatedDebugValue counter) { + super(currentTracker.get(), counter); + } + + @Override + long getCounterValue() { + return getCurrentThreadAllocatedBytes(); + } + + @Override + public void close() { + super.close(); + currentTracker.set(parent); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import com.oracle.graal.debug.*; + +public final class MetricImpl extends DebugValue implements DebugMetric { + + public MetricImpl(String name, boolean conditional) { + super(name, conditional); + if (isEnabled()) { + // Allows for zero-count metrics to be shown + getCurrentValue(); + } + } + + public void increment() { + add(1); + } + + public void add(long value) { + if (isEnabled()) { + super.addToCurrentValue(value); + } + } + + @Override + public String toString(long value) { + return Long.toString(value); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import static com.oracle.graal.debug.DebugCloseable.*; + +import java.lang.management.*; +import java.util.concurrent.*; + +import jdk.internal.jvmci.debug.*; + +import com.oracle.graal.debug.*; + +public final class TimerImpl extends AccumulatedDebugValue implements DebugTimer { + + private static final ThreadMXBean threadMXBean = Management.getThreadMXBean(); + + /** + * Records the most recent active timer. + */ + private static final ThreadLocal<CloseableCounterImpl> currentTimer = new ThreadLocal<>(); + + static class FlatTimer extends DebugValue implements DebugTimer { + private TimerImpl accm; + + public FlatTimer(String name, boolean conditional) { + super(name + "_Flat", conditional); + } + + @Override + public String toString(long value) { + return valueToString(value); + } + + public TimeUnit getTimeUnit() { + return accm.getTimeUnit(); + } + + public DebugCloseable start() { + return accm.start(); + } + } + + public TimerImpl(String name, boolean conditional) { + super(name, conditional, new FlatTimer(name, conditional)); + ((FlatTimer) flat).accm = this; + } + + @Override + public DebugCloseable start() { + if (!isConditional() || Debug.isTimeEnabled()) { + AbstractTimer result; + if (threadMXBean.isCurrentThreadCpuTimeSupported()) { + result = new CpuTimeTimer(this); + } else { + result = new SystemNanosTimer(this); + } + currentTimer.set(result); + return result; + } else { + return VOID_CLOSEABLE; + } + } + + public static String valueToString(long value) { + return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10); + } + + public DebugTimer getFlat() { + return (FlatTimer) flat; + } + + @Override + public String toString(long value) { + return valueToString(value); + } + + public TimeUnit getTimeUnit() { + return TimeUnit.NANOSECONDS; + } + + private abstract static class AbstractTimer extends CloseableCounterImpl implements DebugCloseable { + + private AbstractTimer(AccumulatedDebugValue counter) { + super(currentTimer.get(), counter); + } + + @Override + public void close() { + super.close(); + currentTimer.set(parent); + } + } + + private final class SystemNanosTimer extends AbstractTimer { + + public SystemNanosTimer(TimerImpl timer) { + super(timer); + } + + @Override + protected long getCounterValue() { + return System.nanoTime(); + } + } + + private final class CpuTimeTimer extends AbstractTimer { + + public CpuTimeTimer(TimerImpl timer) { + super(timer); + } + + @Override + protected long getCounterValue() { + return threadMXBean.getCurrentThreadCpuTime(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, 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.hotspot.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +import jdk.internal.jvmci.meta.*; + +/** + * @see AMD64HotSpotEpilogueOp + */ +abstract class AMD64HotSpotEpilogueBlockEndOp extends AMD64BlockEndOp { + + protected AMD64HotSpotEpilogueBlockEndOp(LIRInstructionClass<? extends AMD64HotSpotEpilogueBlockEndOp> c, AllocatableValue savedRbp) { + super(c); + this.savedRbp = savedRbp; + } + + @Use({REG, STACK}) private AllocatableValue savedRbp; + + protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + AMD64HotSpotEpilogueOp.leaveFrameAndRestoreRbp(savedRbp, crb, masm); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import static java.lang.Thread.*; + +import java.io.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.hotspot.*; + +import com.sun.management.*; + +@SuppressWarnings("unused") +public final class CompilationStatistics { + + private static final long RESOLUTION = 100000000; + private static final boolean ENABLED = Boolean.getBoolean("jvmci.comp.stats"); + + private static final CompilationStatistics DUMMY = new CompilationStatistics(null, false); + + private static ConcurrentLinkedDeque<CompilationStatistics> list = new ConcurrentLinkedDeque<>(); + + private static final ThreadLocal<Deque<CompilationStatistics>> current = new ThreadLocal<Deque<CompilationStatistics>>() { + + @Override + protected Deque<CompilationStatistics> initialValue() { + return new ArrayDeque<>(); + } + }; + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + private static @interface NotReported { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + private static @interface TimeValue { + } + + private static long zeroTime = System.nanoTime(); + + private static long getThreadAllocatedBytes() { + ThreadMXBean thread = (ThreadMXBean) Management.getThreadMXBean(); + return thread.getThreadAllocatedBytes(currentThread().getId()); + } + + @NotReported private final long startTime; + @NotReported private long threadAllocatedBytesStart; + + private int bytecodeCount; + private int codeSize; + @TimeValue private long duration; + private long memoryUsed; + private final boolean osr; + private final String holder; + private final String name; + private final String signature; + + private CompilationStatistics(HotSpotResolvedJavaMethod method, boolean osr) { + this.osr = osr; + if (method != null) { + holder = method.getDeclaringClass().getName(); + name = method.getName(); + signature = method.getSignature().toMethodDescriptor(); + startTime = System.nanoTime(); + bytecodeCount = method.getCodeSize(); + threadAllocatedBytesStart = getThreadAllocatedBytes(); + } else { + holder = ""; + name = ""; + signature = ""; + startTime = 0; + } + } + + public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) { + if (ENABLED) { + duration = System.nanoTime() - startTime; + codeSize = (int) code.getCodeSize(); + memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart; + if (current.get().getLast() != this) { + throw new RuntimeException("mismatch in finish()"); + } + current.get().removeLast(); + } + } + + public static CompilationStatistics current() { + return current.get().isEmpty() ? null : current.get().getLast(); + } + + public static CompilationStatistics create(HotSpotResolvedJavaMethod method, boolean isOSR) { + if (ENABLED) { + CompilationStatistics stats = new CompilationStatistics(method, isOSR); + list.add(stats); + current.get().addLast(stats); + return stats; + } else { + return DUMMY; + } + } + + @SuppressWarnings("deprecation") + public static void clear(String dumpName) { + if (!ENABLED) { + return; + } + try { + ConcurrentLinkedDeque<CompilationStatistics> snapshot = list; + long snapshotZeroTime = zeroTime; + + list = new ConcurrentLinkedDeque<>(); + zeroTime = System.nanoTime(); + + Date now = new Date(); + String dateString = (now.getYear() + 1900) + "-" + (now.getMonth() + 1) + "-" + now.getDate() + "-" + now.getHours() + "" + now.getMinutes(); + + dumpCompilations(snapshot, dumpName, dateString); + + try (FileOutputStream fos = new FileOutputStream("timeline_" + dateString + "_" + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) { + + long[] timeSpent = new long[10000]; + int maxTick = 0; + for (CompilationStatistics stats : snapshot) { + long start = stats.startTime - snapshotZeroTime; + long duration = stats.duration; + if (start < 0) { + duration -= -start; + start = 0; + } + + int tick = (int) (start / RESOLUTION); + long timeLeft = RESOLUTION - (start % RESOLUTION); + + while (tick < timeSpent.length && duration > 0) { + if (tick > maxTick) { + maxTick = tick; + } + timeSpent[tick] += Math.min(timeLeft, duration); + duration -= timeLeft; + tick++; + timeLeft = RESOLUTION; + } + } + String timelineName = System.getProperty("stats.timeline.name"); + if (timelineName != null && !timelineName.isEmpty()) { + out.print(timelineName + "\t"); + } + for (int i = 0; i <= maxTick; i++) { + out.print((timeSpent[i] * 100 / RESOLUTION) + "\t"); + } + out.println(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected static void dumpCompilations(ConcurrentLinkedDeque<CompilationStatistics> snapshot, String dumpName, String dateString) throws IllegalAccessException, FileNotFoundException { + String fileName = "compilations_" + dateString + "_" + dumpName + ".csv"; + try (PrintStream out = new PrintStream(fileName)) { + // output the list of all compilations + + Field[] declaredFields = CompilationStatistics.class.getDeclaredFields(); + ArrayList<Field> fields = new ArrayList<>(); + for (Field field : declaredFields) { + if (!Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(NotReported.class)) { + fields.add(field); + } + } + for (Field field : fields) { + out.print(field.getName() + "\t"); + } + out.println(); + for (CompilationStatistics stats : snapshot) { + for (Field field : fields) { + if (field.isAnnotationPresent(TimeValue.class)) { + double value = field.getLong(stats) / 1000000d; + out.print(String.format(Locale.ENGLISH, "%.3f", value) + "\t"); + } else { + out.print(field.get(stats) + "\t"); + } + } + out.println(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import static jdk.internal.jvmci.common.UnsafeAccess.*; +import static jdk.internal.jvmci.compiler.Compiler.*; + +import java.util.concurrent.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.debug.internal.*; + +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.compiler.Compiler; +import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.hotspot.events.*; +import jdk.internal.jvmci.hotspot.events.EventProvider.CompilationEvent; +import jdk.internal.jvmci.hotspot.events.EventProvider.CompilerFailureEvent; +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.service.*; + +//JaCoCo Exclude + +public class CompilationTask { + + private static final DebugMetric BAILOUTS = Debug.metric("Bailouts"); + + private static final EventProvider eventProvider; + static { + EventProvider provider = Services.loadSingle(EventProvider.class, false); + if (provider == null) { + eventProvider = new EmptyEventProvider(); + } else { + eventProvider = provider; + } + } + private static final Compiler compiler = Services.loadSingle(Compiler.class, true); + + private final HotSpotResolvedJavaMethod method; + private final int entryBCI; + private final int id; + + /** + * Specifies whether the compilation result is installed as the + * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method. + */ + private final boolean installAsDefault; + + static class Lazy { + /** + * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the + * current compiler thread, e.g. total allocated bytes. + */ + static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean(); + } + + /** + * The address of the JVMCIEnv associated with this compilation or 0L if no such object exists. + */ + private final long jvmciEnv; + + public CompilationTask(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id, boolean installAsDefault) { + this.method = method; + this.entryBCI = entryBCI; + this.id = id; + this.jvmciEnv = jvmciEnv; + this.installAsDefault = installAsDefault; + } + + public ResolvedJavaMethod getMethod() { + return method; + } + + /** + * Returns the compilation id of this task. + * + * @return compile id + */ + public int getId() { + return id; + } + + public int getEntryBCI() { + return entryBCI; + } + + /** + * Time spent in compilation. + */ + private static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); + + /** + * Meters the {@linkplain CompilationResult#getBytecodeSize() bytecodes} compiled. + */ + private static final DebugMetric CompiledBytecodes = Debug.metric("CompiledBytecodes"); + + public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); + + public void runCompilation() { + HotSpotVMConfig config = HotSpotJVMCIRuntime.runtime().getConfig(); + final long threadId = Thread.currentThread().getId(); + long startCompilationTime = System.nanoTime(); + HotSpotInstalledCode installedCode = null; + final boolean isOSR = entryBCI != Compiler.INVOCATION_ENTRY_BCI; + + // Log a compilation event. + CompilationEvent compilationEvent = eventProvider.newCompilationEvent(); + + // If there is already compiled code for this method on our level we simply return. + // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we + // only need to check for that value. + if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) { + return; + } + + CompilationResult result = null; + try (DebugCloseable a = CompilationTime.start()) { + CompilationStatistics stats = CompilationStatistics.create(method, isOSR); + final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); + final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); + if (printCompilation) { + TTY.println(getMethodDescription() + "..."); + } + + TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); + final long start; + final long allocatedBytesBefore; + if (printAfterCompilation || printCompilation) { + start = System.currentTimeMillis(); + allocatedBytesBefore = printAfterCompilation || printCompilation ? Lazy.threadMXBean.getThreadAllocatedBytes(threadId) : 0L; + } else { + start = 0L; + allocatedBytesBefore = 0L; + } + + try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { + // Begin the compilation event. + compilationEvent.begin(); + + result = compiler.compile(method, entryBCI, mustRecordMethodInlining(config)); + + result.setId(getId()); + } catch (Throwable e) { + throw Debug.handle(e); + } finally { + // End the compilation event. + compilationEvent.end(); + + filter.remove(); + + if (printAfterCompilation || printCompilation) { + final long stop = System.currentTimeMillis(); + final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1; + final long allocatedBytesAfter = Lazy.threadMXBean.getThreadAllocatedBytes(threadId); + final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024; + + if (printAfterCompilation) { + TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes)); + } else if (printCompilation) { + TTY.println(String.format("%-6d JVMCI %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes)); + } + } + } + + try (DebugCloseable b = CodeInstallationTime.start()) { + installedCode = (HotSpotInstalledCode) installMethod(result); + } + stats.finish(method, installedCode); + } catch (BailoutException bailout) { + BAILOUTS.increment(); + if (ExitVMOnBailout.getValue()) { + TTY.out.println(method.format("Bailout in %H.%n(%p)")); + bailout.printStackTrace(TTY.out); + System.exit(-1); + } else if (PrintBailout.getValue()) { + TTY.out.println(method.format("Bailout in %H.%n(%p)")); + bailout.printStackTrace(TTY.out); + } + } catch (Throwable t) { + if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) { + t.printStackTrace(TTY.out); + } + + // Log a failure event. + CompilerFailureEvent event = eventProvider.newCompilerFailureEvent(); + if (event.shouldWrite()) { + event.setCompileId(getId()); + event.setMessage(t.getMessage()); + event.commit(); + } + + if (ExitVMOnException.getValue()) { + System.exit(-1); + } + } finally { + int compiledBytecodes = 0; + int codeSize = 0; + if (result != null) { + compiledBytecodes = result.getBytecodeSize(); + } + if (installedCode != null) { + codeSize = installedCode.getSize(); + } + CompiledBytecodes.add(compiledBytecodes); + + // Log a compilation event. + if (compilationEvent.shouldWrite()) { + compilationEvent.setMethod(method.format("%H.%n(%p)")); + compilationEvent.setCompileId(getId()); + compilationEvent.setCompileLevel(config.compilationLevelFullOptimization); + compilationEvent.setSucceeded(result != null && installedCode != null); + compilationEvent.setIsOsr(isOSR); + compilationEvent.setCodeSize(codeSize); + compilationEvent.setInlinedBytes(compiledBytecodes); + compilationEvent.commit(); + } + + if (jvmciEnv != 0) { + long ctask = unsafe.getAddress(jvmciEnv + config.jvmciEnvTaskOffset); + assert ctask != 0L; + unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, compiledBytecodes); + } + long compilationTime = System.nanoTime() - startCompilationTime; + if ((config.ciTime || config.ciTimeEach) && installedCode != null) { + long timeUnitsPerSecond = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS); + CompilerToVM c2vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM(); + c2vm.notifyCompilationStatistics(id, method, entryBCI != Compiler.INVOCATION_ENTRY_BCI, compiledBytecodes, compilationTime, timeUnitsPerSecond, installedCode); + } + } + } + + /** + * Determines whether to disable method inlining recording for the method being compiled. + */ + private boolean mustRecordMethodInlining(HotSpotVMConfig config) { + if (config.ciTime || config.ciTimeEach || CompiledBytecodes.isEnabled()) { + return true; + } + if (jvmciEnv == 0 || unsafe.getByte(jvmciEnv + config.jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0) { + return true; + } + return false; + } + + private String getMethodDescription() { + return String.format("%-6d JVMCI %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(), + entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); + } + + private InstalledCode installMethod(final CompilationResult compResult) { + final HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getCodeCache(); + InstalledCode installedCode = null; + try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { + installedCode = codeCache.installMethod(method, compResult, jvmciEnv, installAsDefault); + } catch (Throwable e) { + throw Debug.handle(e); + } + return installedCode; + } + + @Override + public String toString() { + return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; + } + + /** + * Compiles a method to machine code. + */ + public static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) { + // Ensure a debug configuration for this thread is initialized + if (Debug.isEnabled() && DebugScope.getConfig() == null) { + DebugEnvironment.initialize(TTY.out); + } + + CompilationTask task = new CompilationTask(method, entryBCI, jvmciEnv, id, true); + try (DebugConfigScope dcs = Debug.setConfig(new TopLevelDebugConfig())) { + task.runCompilation(); + } + return; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import static jdk.internal.jvmci.compiler.Compiler.*; + +import java.io.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.util.jar.*; +import java.util.stream.*; + +import jdk.internal.jvmci.compiler.Compiler; +import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.options.*; +import jdk.internal.jvmci.options.OptionUtils.OptionConsumer; +import jdk.internal.jvmci.options.OptionValue.OverrideScope; +import jdk.internal.jvmci.runtime.*; + +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; + +import static com.oracle.graal.hotspot.CompileTheWorld.Options.*; + +/** + * This class implements compile-the-world functionality with JVMCI. + */ +public final class CompileTheWorld { + + /** + * Magic token to trigger reading files from the boot class path. + */ + public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; + + public static class Options { + // @formatter:off + @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) + public static final OptionValue<String> CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH); + @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) + public static final OptionValue<Boolean> CompileTheWorldVerbose = new OptionValue<>(true); + @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) + public static final OptionValue<Integer> CompileTheWorldIterations = new OptionValue<>(1); + @Option(help = "Only compile methods matching this filter", type = OptionType.Debug) + public static final OptionValue<String> CompileTheWorldMethodFilter = new OptionValue<>(null); + @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug) + public static final OptionValue<String> CompileTheWorldExcludeMethodFilter = new OptionValue<>(null); + @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) + public static final OptionValue<Integer> CompileTheWorldStartAt = new OptionValue<>(1); + @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) + public static final OptionValue<Integer> CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); + @Option(help = "Option value overrides to use during compile the world. For example, " + + "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " + + "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug) + public static final OptionValue<String> CompileTheWorldConfig = new OptionValue<>(null); + + @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug) + public static final OptionValue<Boolean> CompileTheWorldMultiThreaded = new OptionValue<>(false); + @Option(help = "Number of threads to use for multithreaded CTW. Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug) + public static final OptionValue<Integer> CompileTheWorldThreads = new OptionValue<>(0); + // @formatter:on + + /** + * Overrides {@link #CompileTheWorldStartAt} and {@link #CompileTheWorldStopAt} from + * {@code -XX} HotSpot options of the same name if the latter have non-default values. + */ + public static void overrideWithNativeOptions(HotSpotVMConfig c) { + if (c.compileTheWorldStartAt != 1) { + CompileTheWorldStartAt.setValue(c.compileTheWorldStartAt); + } + if (c.compileTheWorldStopAt != Integer.MAX_VALUE) { + CompileTheWorldStopAt.setValue(c.compileTheWorldStopAt); + } + } + } + + /** + * A mechanism for overriding JVMCI options that affect compilation. A {@link Config} object + * should be used in a try-with-resources statement to ensure overriding of options is scoped + * properly. For example: + * + * <pre> + * Config config = ...; + * try (AutoCloseable s = config == null ? null : config.apply()) { + * // perform a JVMCI compilation + * } + * </pre> + */ + @SuppressWarnings("serial") + public static class Config extends HashMap<OptionValue<?>, Object> implements OptionConsumer { + /** + * Creates a {@link Config} object by parsing a set of space separated override options. + * + * @param options a space separated set of option value settings with each option setting in + * a format compatible with + * {@link OptionUtils#parseOption(String, OptionConsumer)}. Ignored if null. + */ + public Config(String options) { + if (options != null) { + for (String option : options.split("\\s+")) { + OptionUtils.parseOption(option, this); + } + } + } + + /** + * Applies the overrides represented by this object. The overrides are in effect until + * {@link OverrideScope#close()} is called on the returned object. + */ + OverrideScope apply() { + return OptionValue.override(this); + } + + public void set(OptionDescriptor desc, Object value) { + put(desc.getOptionValue(), value); + } + } + + /** List of Zip/Jar files to compile (see {@link Options#CompileTheWorldClasspath}). */ + private final String files; + + /** Class index to start compilation at (see {@link Options#CompileTheWorldStartAt}). */ + private final int startAt; + + /** Class index to stop compilation at (see {@link Options#CompileTheWorldStopAt}). */ + private final int stopAt; + + /** Only compile methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] methodFilters; + + /** Exclude methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] excludeMethodFilters; + + // Counters + private int classFileCounter = 0; + private AtomicLong compiledMethodsCounter = new AtomicLong(); + private AtomicLong compileTime = new AtomicLong(); + private AtomicLong memoryUsed = new AtomicLong(); + + private boolean verbose; + private final Config config; + + /** + * Signal that the threads should start compiling in multithreaded mode. + */ + private boolean running; + + private ThreadPoolExecutor threadPool; + + /** + * Creates a compile-the-world instance. + * + * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @param startAt index of the class file to start compilation at + * @param stopAt index of the class file to stop compilation at + * @param methodFilters + * @param excludeMethodFilters + */ + public CompileTheWorld(String files, Config config, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, boolean verbose) { + this.files = files; + this.startAt = startAt; + this.stopAt = stopAt; + this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); + this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); + this.verbose = verbose; + this.config = config; + + // We don't want the VM to exit when a method fails to compile... + config.putIfAbsent(ExitVMOnException, false); + + // ...but we want to see exceptions. + config.putIfAbsent(PrintBailout, true); + config.putIfAbsent(PrintStackTraceOnException, true); + config.putIfAbsent(HotSpotResolvedJavaMethodImpl.Options.UseProfilingInformation, false); + } + + public CompileTheWorld() { + this(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue(), + CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue()); + } + + /** + * Compiles all methods in all classes in the Zip/Jar archive files in + * {@link Options#CompileTheWorldClasspath}. If {@link Options#CompileTheWorldClasspath} + * contains the magic token {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the + * files from the boot class path. + */ + public void compile() throws Throwable { + // By default only report statistics for the CTW threads themselves + if (JVMCIDebugConfig.DebugValueThreadFilter.hasDefaultValue()) { + JVMCIDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld"); + } + + if (SUN_BOOT_CLASS_PATH.equals(files)) { + final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); + String bcpFiles = ""; + for (int i = 0; i < entries.length; i++) { + final String entry = entries[i]; + + // We stop at rt.jar, unless it is the first boot class path entry. + if (entry.endsWith("rt.jar") && (i > 0)) { + break; + } + if (i > 0) { + bcpFiles += File.pathSeparator; + } + bcpFiles += entry; + } + compile(bcpFiles); + } else { + compile(files); + } + } + + public void println() { + println(""); + } + + public void println(String format, Object... args) { + println(String.format(format, args)); + } + + public void println(String s) { + if (verbose) { + TTY.println(s); + } + } + + @SuppressWarnings("unused") + private static void dummy() { + } + + /** + * Compiles all methods in all classes in the Zip/Jar files passed. + * + * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @throws IOException + */ + private void compile(String fileList) throws IOException { + final String[] entries = fileList.split(File.pathSeparator); + long start = System.currentTimeMillis(); + + CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { + public JVMCIDebugConfig getDebugConfig() { + if (Debug.isEnabled() && DebugScope.getConfig() == null) { + return DebugEnvironment.initialize(System.out); + } + return null; + } + }); + + try { + // compile dummy method to get compiler initilized outside of the config debug override. + HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( + CompileTheWorld.class.getDeclaredMethod("dummy")); + CompilationTask task = new CompilationTask(dummyMethod, Compiler.INVOCATION_ENTRY_BCI, 0L, dummyMethod.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false); + task.runCompilation(); + } catch (NoSuchMethodException | SecurityException e1) { + e1.printStackTrace(); + } + + /* + * Always use a thread pool, even for single threaded mode since it simplifies the use of + * DebugValueThreadFilter to filter on the thread names. + */ + int threadCount = 1; + if (Options.CompileTheWorldMultiThreaded.getValue()) { + threadCount = Options.CompileTheWorldThreads.getValue(); + if (threadCount == 0) { + threadCount = Runtime.getRuntime().availableProcessors(); + } + } else { + running = true; + } + threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory); + + try (OverrideScope s = config.apply()) { + for (int i = 0; i < entries.length; i++) { + final String entry = entries[i]; + + // For now we only compile all methods in all classes in zip/jar files. + if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { + println("CompileTheWorld : Skipped classes in " + entry); + println(); + continue; + } + + if (methodFilters == null || methodFilters.length == 0) { + println("CompileTheWorld : Compiling all classes in " + entry); + } else { + String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); + } + if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { + String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); + } + println(); + + URL url = new URL("jar", "", "file:" + entry + "!/"); + ClassLoader loader = new URLClassLoader(new URL[]{url}); + + JarFile jarFile = new JarFile(entry); + Enumeration<JarEntry> e = jarFile.entries(); + + while (e.hasMoreElements()) { + JarEntry je = e.nextElement(); + if (je.isDirectory() || !je.getName().endsWith(".class")) { + continue; + } + + // Are we done? + if (classFileCounter >= stopAt) { + break; + } + + String className = je.getName().substring(0, je.getName().length() - ".class".length()); + String dottedClassName = className.replace('/', '.'); + classFileCounter++; + + if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) { + continue; + } + if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) { + continue; + } + + if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) { + continue; + } + + try { + // Load and initialize class + Class<?> javaClass = Class.forName(dottedClassName, true, loader); + + // Pre-load all classes in the constant pool. + try { + HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass); + ConstantPool constantPool = objectType.constantPool(); + for (int cpi = 1; cpi < constantPool.length(); cpi++) { + constantPool.loadReferencedType(cpi, HotSpotConstantPool.Bytecodes.LDC); + } + } catch (Throwable t) { + // If something went wrong during pre-loading we just ignore it. + println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); + } + + // Are we compiling this class? + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + if (classFileCounter >= startAt) { + println("CompileTheWorld (%d) : %s", classFileCounter, className); + + // Compile each constructor/method in the class. + for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); + if (canBeCompiled(javaMethod, constructor.getModifiers())) { + compileMethod(javaMethod); + } + } + for (Method method : javaClass.getDeclaredMethods()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); + if (canBeCompiled(javaMethod, method.getModifiers())) { + compileMethod(javaMethod); + } + } + } + } catch (Throwable t) { + println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); + t.printStackTrace(); + } + } + jarFile.close(); + } + } + + if (!running) { + startThreads(); + } + int wakeups = 0; + while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { + if (wakeups % 15 == 0) { + TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); + } + try { + threadPool.awaitTermination(1, TimeUnit.SECONDS); + wakeups++; + } catch (InterruptedException e) { + } + } + threadPool = null; + + long elapsedTime = System.currentTimeMillis() - start; + + println(); + if (Options.CompileTheWorldMultiThreaded.getValue()) { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, + compileTime.get(), memoryUsed.get()); + } else { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); + } + } + + private synchronized void startThreads() { + running = true; + // Wake up any waiting threads + notifyAll(); + } + + private synchronized void waitToRun() { + while (!running) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { + if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { + return; + } + if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { + return; + } + Future<?> task = threadPool.submit(new Runnable() { + public void run() { + waitToRun(); + try (OverrideScope s = config.apply()) { + compileMethod(method, classFileCounter); + } + } + }); + if (threadPool.getCorePoolSize() == 1) { + task.get(); + } + } + + /** + * Compiles a method and gathers some statistics. + */ + private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { + try { + long start = System.currentTimeMillis(); + long allocatedAtStart = MemUseTrackerImpl.getCurrentThreadAllocatedBytes(); + + CompilationTask task = new CompilationTask(method, Compiler.INVOCATION_ENTRY_BCI, 0L, method.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false); + task.runCompilation(); + + memoryUsed.getAndAdd(MemUseTrackerImpl.getCurrentThreadAllocatedBytes() - allocatedAtStart); + compileTime.getAndAdd(System.currentTimeMillis() - start); + compiledMethodsCounter.incrementAndGet(); + } catch (Throwable t) { + // Catch everything and print a message + println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); + t.printStackTrace(TTY.out); + } + } + + /** + * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). + * + * @return true if it can be compiled, false otherwise + */ + private static boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { + if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return false; + } + HotSpotVMConfig c = HotSpotJVMCIRuntime.runtime().getConfig(); + if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { + return false; + } + // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods + if (!javaMethod.canBeInlined()) { + return false; + } + // Skip @Snippets for now + for (Annotation annotation : javaMethod.getAnnotations()) { + if (annotation.annotationType().getName().equals("com.oracle.graal.replacements.Snippet")) { + return false; + } + } + return true; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/ConstantPhiTest.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, 2015, 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.jtt.backend; + +import static com.oracle.graal.api.directives.GraalDirectives.*; + +import java.lang.reflect.*; + +import jdk.internal.jvmci.options.*; +import jdk.internal.jvmci.options.OptionValue.OverrideScope; + +import org.junit.*; + +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.jtt.*; + +public class ConstantPhiTest extends JTTTest { + + public static int test(int i, int x) throws Throwable { + int r; + if (injectBranchProbability(LIKELY_PROBABILITY, i < 0)) { + r = 42; + } else { + r = x; + } + destroyCallerSavedValues(); + return r; + } + + protected static void destroyCallerSavedValues() throws Throwable { + Class<ConstantPhiTest> c = ConstantPhiTest.class; + Method m = c.getMethod("destroyCallerSavedValues0"); + m.invoke(null); + } + + public static void destroyCallerSavedValues0() { + } + + @Test + public void run0() { + try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) { + runTest("test", 0, 0xDEADDEAD); + } + } + + @Test + public void run1() { + try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) { + runTest("test", -1, 0xDEADDEAD); + } + } + + @Test + public void run2() { + try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) { + runTest("test", 1, 0xDEADDEAD); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BlockEndOp.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 2015, 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.lir.amd64; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.asm.*; + +public abstract class AMD64BlockEndOp extends AbstractBlockEndOp { + + public static final LIRInstructionClass<AMD64BlockEndOp> TYPE = LIRInstructionClass.create(AMD64BlockEndOp.class); + + protected AMD64BlockEndOp(LIRInstructionClass<? extends AMD64BlockEndOp> c) { + super(c); + } + + @Override + public final void emitCode(CompilationResultBuilder crb) { + emitCode(crb, (AMD64MacroAssembler) crb.asm); + } + + public abstract void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2015, 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.lir.sparc; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; + +import jdk.internal.jvmci.meta.*; + +public abstract class SPARCBlockEndOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<SPARCBlockEndOp> TYPE = LIRInstructionClass.create(SPARCBlockEndOp.class); + + @Alive({REG, STACK, CONST}) private Value[] outgoingValues; + private int size; + + protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c) { + this(c, null); + } + + protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c, SizeEstimate sizeEstimate) { + super(c, sizeEstimate); + this.outgoingValues = Value.NO_VALUES; + this.size = 0; + } + + public void setOutgoingValues(Value[] values) { + assert outgoingValues.length == 0; + assert values != null; + outgoingValues = values; + size = values.length; + } + + public int getOutgoingSize() { + return size; + } + + public Value getOutgoingValue(int idx) { + assert checkRange(idx); + return outgoingValues[idx]; + } + + private boolean checkRange(int idx) { + return idx < size; + } + + public void clearOutgoingValues() { + outgoingValues = Value.NO_VALUES; + size = 0; + } + + public int addOutgoingValues(Value[] v) { + + int t = size + v.length; + if (t >= outgoingValues.length) { + Value[] newArray = new Value[t]; + System.arraycopy(outgoingValues, 0, newArray, 0, size); + outgoingValues = newArray; + } + System.arraycopy(v, 0, outgoingValues, size, v.length); + size = t; + return t; + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ArithmeticOperation.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, 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.nodes; + +/** + * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side + * effect. + */ +public interface ArithmeticOperation { +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeCheckHints.java Fri Jul 24 02:11:18 2015 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import java.util.*; + +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.meta.Assumptions.*; +import jdk.internal.jvmci.meta.JavaTypeProfile.*; + +/** + * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof) based + * on the target type of the check and any profiling information available for the instruction. + */ +public class TypeCheckHints { + + /** + * A receiver type profiled in a type check instruction. + */ + public static class Hint { + + /** + * A type seen while profiling a type check instruction. + */ + public final ResolvedJavaType type; + + /** + * Specifies if {@link #type} is a sub-type of the checked type. + */ + public final boolean positive; + + Hint(ResolvedJavaType type, boolean positive) { + this.type = type; + this.positive = positive; + } + } + + private static final Hint[] NO_HINTS = {}; + + /** + * If non-null, then this is the only type that could pass the type check because the target of + * the type check is a final class or has been speculated to be a final class and this value is + * the only concrete subclass of the target type. + */ + public final ResolvedJavaType exact; + + /** + * The most likely types that the type check instruction will see. + */ + public final Hint[] hints; + + /** + * The profile from which this information was derived. + */ + public final JavaTypeProfile profile; + + /** + * The total probability that the type check will hit one of the types in {@link #hints}. + */ + public final double hintHitProbability; + + /** + * Derives hint information for use when generating the code for a type check instruction. + * + * @param targetType the target type of the type check + * @param profile the profiling information available for the instruction (if any) + * @param assumptions the object in which speculations are recorded. This is null if + * speculations are not supported. + * @param minHintHitProbability if the probability that the type check will hit one of the + * profiled types (up to {@code maxHints}) is below this value, then {@link #hints} + * will be null + * @param maxHints the maximum length of {@link #hints} + */ + public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { + this.profile = profile; + if (targetType != null && targetType.isLeaf()) { + exact = targetType; + } else { + if (assumptions != null) { + AssumptionResult<ResolvedJavaType> leafConcreteSubtype = targetType == null ? null : targetType.findLeafConcreteSubtype(); + if (leafConcreteSubtype != null) { + assumptions.record(leafConcreteSubtype); + exact = leafConcreteSubtype.getResult(); + } else { + exact = null; + } + } else { + exact = null; + } + } + Double[] hitProbability = {null}; + this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability); + this.hintHitProbability = hitProbability[0]; + } + + private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) { + double hitProb = 0.0d; + Hint[] hintsBuf = NO_HINTS; + if (profile != null) { + double notRecordedTypes = profile.getNotRecordedProbability(); + ProfiledType[] ptypes = profile.getTypes(); + if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { + hintsBuf = new Hint[ptypes.length]; + int hintCount = 0; + for (ProfiledType ptype : ptypes) { + if (targetType != null) { + ResolvedJavaType hintType = ptype.getType(); + hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); + hitProb += ptype.getProbability(); + } + if (hintCount == maxHints) { + break; + } + } + if (hitProb >= minHintHitProbability) { + if (hintsBuf.length != hintCount || hintCount > maxHints) { + hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); + } + } else { + hintsBuf = NO_HINTS; + hitProb = 0.0d; + } + } + } + hitProbability[0] = hitProb; + return hintsBuf; + } +}
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ArithmeticOperation.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013, 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 jdk.internal.jvmci.code; - -/** - * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side - * effect. - */ -public interface ArithmeticOperation { -}
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/TypeCheckHints.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * 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 jdk.internal.jvmci.code; - -import java.util.*; - -import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.meta.Assumptions.*; -import jdk.internal.jvmci.meta.JavaTypeProfile.*; - -/** - * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof) based - * on the target type of the check and any profiling information available for the instruction. - */ -public class TypeCheckHints { - - /** - * A receiver type profiled in a type check instruction. - */ - public static class Hint { - - /** - * A type seen while profiling a type check instruction. - */ - public final ResolvedJavaType type; - - /** - * Specifies if {@link #type} is a sub-type of the checked type. - */ - public final boolean positive; - - Hint(ResolvedJavaType type, boolean positive) { - this.type = type; - this.positive = positive; - } - } - - private static final Hint[] NO_HINTS = {}; - - /** - * If non-null, then this is the only type that could pass the type check because the target of - * the type check is a final class or has been speculated to be a final class and this value is - * the only concrete subclass of the target type. - */ - public final ResolvedJavaType exact; - - /** - * The most likely types that the type check instruction will see. - */ - public final Hint[] hints; - - /** - * The profile from which this information was derived. - */ - public final JavaTypeProfile profile; - - /** - * The total probability that the type check will hit one of the types in {@link #hints}. - */ - public final double hintHitProbability; - - /** - * Derives hint information for use when generating the code for a type check instruction. - * - * @param targetType the target type of the type check - * @param profile the profiling information available for the instruction (if any) - * @param assumptions the object in which speculations are recorded. This is null if - * speculations are not supported. - * @param minHintHitProbability if the probability that the type check will hit one of the - * profiled types (up to {@code maxHints}) is below this value, then {@link #hints} - * will be null - * @param maxHints the maximum length of {@link #hints} - */ - public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { - this.profile = profile; - if (targetType != null && targetType.isLeaf()) { - exact = targetType; - } else { - if (assumptions != null) { - AssumptionResult<ResolvedJavaType> leafConcreteSubtype = targetType == null ? null : targetType.findLeafConcreteSubtype(); - if (leafConcreteSubtype != null) { - assumptions.record(leafConcreteSubtype); - exact = leafConcreteSubtype.getResult(); - } else { - exact = null; - } - } else { - exact = null; - } - } - Double[] hitProbability = {null}; - this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability); - this.hintHitProbability = hitProbability[0]; - } - - private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) { - double hitProb = 0.0d; - Hint[] hintsBuf = NO_HINTS; - if (profile != null) { - double notRecordedTypes = profile.getNotRecordedProbability(); - ProfiledType[] ptypes = profile.getTypes(); - if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { - hintsBuf = new Hint[ptypes.length]; - int hintCount = 0; - for (ProfiledType ptype : ptypes) { - if (targetType != null) { - ResolvedJavaType hintType = ptype.getType(); - hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); - hitProb += ptype.getProbability(); - } - if (hintCount == maxHints) { - break; - } - } - if (hitProb >= minHintHitProbability) { - if (hintsBuf.length != hintCount || hintCount > maxHints) { - hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); - } - } else { - hintsBuf = NO_HINTS; - hitProb = 0.0d; - } - } - } - hitProbability[0] = hitProb; - return hintsBuf; - } -}
--- a/jvmci/jdk.internal.jvmci.compiler/src/jdk/internal/jvmci/compiler/CompilerThread.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2012, 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 jdk.internal.jvmci.compiler; - -import jdk.internal.jvmci.compiler.CompilerThreadFactory.*; -import jdk.internal.jvmci.debug.*; - -/** - * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the - * context of a thread-local {@linkplain JVMCIDebugConfig debug configuration}. - */ -public class CompilerThread extends Thread { - - private final DebugConfigAccess debugConfigAccess; - - public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { - super(r); - this.setName(namePrefix + "-" + this.getId()); - this.setPriority(Thread.MAX_PRIORITY); - this.setDaemon(true); - this.debugConfigAccess = debugConfigAccess; - } - - @Override - public void run() { - JVMCIDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); - setContextClassLoader(getClass().getClassLoader()); - try { - super.run(); - } finally { - if (debugConfig != null) { - for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { - try { - dumpHandler.close(); - } catch (Throwable t) { - } - } - } - } - } -}
--- a/jvmci/jdk.internal.jvmci.compiler/src/jdk/internal/jvmci/compiler/CompilerThreadFactory.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * 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 jdk.internal.jvmci.compiler; - -import java.util.concurrent.*; - -import jdk.internal.jvmci.debug.*; - -/** - * Facility for creating {@linkplain CompilerThread compiler threads}. - */ -public class CompilerThreadFactory implements ThreadFactory { - - /** - * Capability to get a thread-local debug configuration for the current thread. - */ - public interface DebugConfigAccess { - /** - * Get a thread-local debug configuration for the current thread. This will be null if - * debugging is {@linkplain Debug#isEnabled() disabled}. - */ - JVMCIDebugConfig getDebugConfig(); - } - - protected final String threadNamePrefix; - protected final DebugConfigAccess debugConfigAccess; - - public CompilerThreadFactory(String threadNamePrefix, DebugConfigAccess debugConfigAccess) { - this.threadNamePrefix = threadNamePrefix; - this.debugConfigAccess = debugConfigAccess; - } - - public Thread newThread(Runnable r) { - return new CompilerThread(r, threadNamePrefix, debugConfigAccess); - } -}
--- a/jvmci/jdk.internal.jvmci.debug.test/src/jdk/internal/jvmci/debug/test/DebugHistogramTest.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug.test; - -import java.io.*; - -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.debug.internal.*; - -import org.junit.*; - -public class DebugHistogramTest { - - @Test - public void testEmptyHistogram() { - DebugHistogram histogram = Debug.createHistogram("TestHistogram"); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); - String line = outputStream.toString().split("\r?\n")[0]; - Assert.assertEquals("TestHistogram is empty.", line); - - outputStream.reset(); - new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); - Assert.assertEquals("", outputStream.toString()); - } - - @Test - public void testSingleEntryHistogram() { - DebugHistogram histogram = Debug.createHistogram("TestHistogram"); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - histogram.add(new Integer(1)); - histogram.add(new Integer(1)); - new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); - String[] lines = outputStream.toString().split("\r?\n"); - // @formatter:off - String[] expected = { - "TestHistogram has 1 unique elements and 2 total elements:", - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - "| 1 | 2 | ==================================================================================================== |", - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" - }; - // @formatter:on - Assert.assertArrayEquals(expected, lines); - - outputStream.reset(); - new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); - lines = outputStream.toString().split("\r?\n"); - // @formatter:off - expected = new String[] { - "TestHistogram <- c(2);", - "names(TestHistogram) <- c(\"1\");" - }; - // @formatter:on - Assert.assertArrayEquals(expected, lines); - } - - @Test - public void testMultipleEntryHistogram() { - DebugHistogram histogram = Debug.createHistogram("TestHistogram"); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - histogram.add(new Integer(1)); - histogram.add(new Integer(2)); - histogram.add(new Integer(2)); - new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); - String[] lines = outputStream.toString().split("\r?\n"); - // @formatter:off - String[] expected = new String[] { - "TestHistogram has 2 unique elements and 3 total elements:", - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - "| 2 | 2 | ==================================================================================================== |", - "| 1 | 1 | ================================================== |", - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" - }; - // @formatter:on - Assert.assertArrayEquals(expected, lines); - - outputStream.reset(); - new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); - lines = outputStream.toString().split("\r?\n"); - // @formatter:off - expected = new String[] { - "TestHistogram <- c(2, 1);", - "names(TestHistogram) <- c(\"2\", \"1\");" - }; - // @formatter:on - Assert.assertArrayEquals(expected, lines); - } - - @Test - public void testTooLongValueString() { - DebugHistogram histogram = Debug.createHistogram("TestHistogram"); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - histogram.add("MyCustomValue"); - new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10, 1).print(histogram); - String[] lines = outputStream.toString().split("\r?\n"); - Assert.assertEquals(4, lines.length); - Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]); - Assert.assertEquals("----------------------------------------", lines[1]); - Assert.assertEquals("| MyCusto... | 1 | ========== |", lines[2]); - Assert.assertEquals("----------------------------------------", lines[3]); - } -}
--- a/jvmci/jdk.internal.jvmci.debug.test/src/jdk/internal/jvmci/debug/test/DebugTimerTest.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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 jdk.internal.jvmci.debug.test; - -import static org.junit.Assert.*; - -import java.lang.management.*; - -import jdk.internal.jvmci.debug.*; - -import org.junit.*; - -public class DebugTimerTest { - - private static final ThreadMXBean threadMXBean = Management.getThreadMXBean(); - - @Before - public void checkCapabilities() { - Assume.assumeTrue("skipping management interface test", threadMXBean.isCurrentThreadCpuTimeSupported()); - } - - /** - * Actively spins the current thread for at least a given number of milliseconds in such a way - * that timers for the current thread keep ticking over. - * - * @return the number of milliseconds actually spent spinning which is guaranteed to be >= - * {@code ms} - */ - private static long spin(long ms) { - long start = threadMXBean.getCurrentThreadCpuTime(); - do { - long durationMS = (threadMXBean.getCurrentThreadCpuTime() - start) / 1000; - if (durationMS >= ms) { - return durationMS; - } - } while (true); - } - - @Test - public void test1() { - DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); - try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { - - DebugTimer timerA = Debug.timer("TimerA"); - DebugTimer timerB = Debug.timer("TimerB"); - - long spinA; - long spinB; - - try (DebugCloseable a1 = timerA.start()) { - spinA = spin(50); - try (DebugCloseable b1 = timerB.start()) { - spinB = spin(50); - } - } - - Assert.assertTrue(timerB.getCurrentValue() < timerA.getCurrentValue()); - if (timerA.getFlat() != null && timerB.getFlat() != null) { - assertTrue(spinB >= spinA || timerB.getFlat().getCurrentValue() < timerA.getFlat().getCurrentValue()); - assertEquals(timerA.getFlat().getCurrentValue(), timerA.getCurrentValue() - timerB.getFlat().getCurrentValue(), 10D); - } - } - } - - @Test - public void test2() { - DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); - try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { - DebugTimer timerC = Debug.timer("TimerC"); - try (DebugCloseable c1 = timerC.start()) { - spin(50); - try (DebugCloseable c2 = timerC.start()) { - spin(50); - try (DebugCloseable c3 = timerC.start()) { - spin(50); - try (DebugCloseable c4 = timerC.start()) { - spin(50); - try (DebugCloseable c5 = timerC.start()) { - spin(50); - } - } - } - } - } - if (timerC.getFlat() != null) { - assertEquals(timerC.getFlat().getCurrentValue(), timerC.getCurrentValue()); - } - } - } - - @Test - public void test3() { - DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); - try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { - - DebugTimer timerD = Debug.timer("TimerD"); - DebugTimer timerE = Debug.timer("TimerE"); - - long spinD1; - long spinE; - - try (DebugCloseable d1 = timerD.start()) { - spinD1 = spin(50); - try (DebugCloseable e1 = timerE.start()) { - spinE = spin(50); - try (DebugCloseable d2 = timerD.start()) { - spin(50); - try (DebugCloseable d3 = timerD.start()) { - spin(50); - } - } - } - } - - Assert.assertTrue(timerE.getCurrentValue() < timerD.getCurrentValue()); - if (timerD.getFlat() != null && timerE.getFlat() != null) { - assertTrue(spinE >= spinD1 || timerE.getFlat().getCurrentValue() < timerD.getFlat().getCurrentValue()); - assertEquals(timerD.getFlat().getCurrentValue(), timerD.getCurrentValue() - timerE.getFlat().getCurrentValue(), 10D); - } - } - } -}
--- a/jvmci/jdk.internal.jvmci.debug/overview.html Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- - -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. Oracle designates this -particular file as subject to the "Classpath" exception as provided -by Oracle in the LICENSE file that accompanied this code. - -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. ---> - -</head> -<body> - -Documentation for the <code>jdk.internal.jvmci.debug</code> project. - -</body> -</html>
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/AnsiColor.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2014, 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 jdk.internal.jvmci.debug; - -/** - * Ansi terminal color escape codes. - */ -public final class AnsiColor { - /** Foreground black. */ - public static final String BLACK = "\u001b[30m"; - /** Foreground red. */ - public static final String RED = "\u001b[31m"; - /** Foreground green. */ - public static final String GREEN = "\u001b[32m"; - /** Foreground yellow. */ - public static final String YELLOW = "\u001b[33m"; - /** Foreground blue. */ - public static final String BLUE = "\u001b[34m"; - /** Foreground magenta. */ - public static final String MAGENTA = "\u001b[35m"; - /** Foreground cyan. */ - public static final String CYAN = "\u001b[36m"; - /** Foreground white. */ - public static final String WHITE = "\u001b[37m"; - - /** Foreground bold black. */ - public static final String BOLD_BLACK = "\u001b[30;1m"; - /** Foreground bold red. */ - public static final String BOLD_RED = "\u001b[31;1m"; - /** Foreground bold green. */ - public static final String BOLD_GREEN = "\u001b[32;1m"; - /** Foreground bold yellow. */ - public static final String BOLD_YELLOW = "\u001b[33;1m"; - /** Foreground bold blue. */ - public static final String BOLD_BLUE = "\u001b[34;1m"; - /** Foreground bold magenta. */ - public static final String BOLD_MAGENTA = "\u001b[35;1m"; - /** Foreground bold cyan. */ - public static final String BOLD_CYAN = "\u001b[36;1m"; - /** Foreground bold white. */ - public static final String BOLD_WHITE = "\u001b[37;1m"; - - /** Background black. */ - public static final String BG_BLACK = "\u001b[40m"; - /** Background red. */ - public static final String BG_RED = "\u001b[41m"; - /** Background green. */ - public static final String BG_GREEN = "\u001b[42m"; - /** Background yellow. */ - public static final String BG_YELLOW = "\u001b[43m"; - /** Background blue. */ - public static final String BG_BLUE = "\u001b[44m"; - /** Background magenta. */ - public static final String BG_MAGENTA = "\u001b[45m"; - /** Background cyan. */ - public static final String BG_CYAN = "\u001b[46m"; - /** Background white. */ - public static final String BG_WHITE = "\u001b[47m"; - - /** Reset. */ - public static final String RESET = "\u001b[0m"; - /** Underline. */ - public static final String UNDERLINED = "\u001b[4m"; - - /** Prevent instantiation. */ - private AnsiColor() { - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Debug.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1551 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import static java.util.FormattableFlags.*; -import static jdk.internal.jvmci.debug.Debug.Initialization.*; -import static jdk.internal.jvmci.debug.DelegatingDebugConfig.Feature.*; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; - -import jdk.internal.jvmci.debug.DelegatingDebugConfig.*; -import jdk.internal.jvmci.debug.internal.*; -import jdk.internal.jvmci.service.*; - -/** - * Scope based debugging facility. This facility is {@link #isEnabled()} if assertions are enabled - * for the {@link Debug} class or the {@value Initialization#INITIALIZER_PROPERTY_NAME} system - * property is {@code "true"} when {@link Debug} is initialized. - */ -public class Debug { - - static { - for (DebugInitializationPropertyProvider p : Services.load(DebugInitializationPropertyProvider.class)) { - p.apply(); - } - } - - /** - * Class to assist with initialization of {@link Debug}. - */ - public static class Initialization { - - public static final String INITIALIZER_PROPERTY_NAME = "jvmci.debug.enable"; - - private static boolean initialized; - - /** - * Determines if {@link Debug} has been initialized. - */ - public static boolean isDebugInitialized() { - return initialized; - } - - } - - @SuppressWarnings("all") - private static boolean initialize() { - boolean assertionsEnabled = false; - assert assertionsEnabled = true; - Initialization.initialized = true; - return assertionsEnabled || Boolean.getBoolean(INITIALIZER_PROPERTY_NAME); - } - - private static final boolean ENABLED = initialize(); - - public static boolean isEnabled() { - return ENABLED; - } - - public static boolean isDumpEnabledForMethod() { - if (!ENABLED) { - return false; - } - DebugConfig config = DebugScope.getConfig(); - if (config == null) { - return false; - } - return config.isDumpEnabledForMethod(); - } - - public static final int DEFAULT_LOG_LEVEL = 2; - - public static boolean isDumpEnabled() { - return isDumpEnabled(DEFAULT_LOG_LEVEL); - } - - public static boolean isDumpEnabled(int dumpLevel) { - return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel); - } - - /** - * Determines if verification is enabled in the current method, regardless of the - * {@linkplain Debug#currentScope() current debug scope}. - * - * @see Debug#verify(Object, String) - */ - public static boolean isVerifyEnabledForMethod() { - if (!ENABLED) { - return false; - } - DebugConfig config = DebugScope.getConfig(); - if (config == null) { - return false; - } - return config.isVerifyEnabledForMethod(); - } - - /** - * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug - * scope}. - * - * @see Debug#verify(Object, String) - */ - public static boolean isVerifyEnabled() { - return ENABLED && DebugScope.getInstance().isVerifyEnabled(); - } - - public static boolean isMeterEnabled() { - return ENABLED && DebugScope.getInstance().isMeterEnabled(); - } - - public static boolean isTimeEnabled() { - return ENABLED && DebugScope.getInstance().isTimeEnabled(); - } - - public static boolean isMemUseTrackingEnabled() { - return ENABLED && DebugScope.getInstance().isMemUseTrackingEnabled(); - } - - public static boolean isLogEnabledForMethod() { - if (!ENABLED) { - return false; - } - DebugConfig config = DebugScope.getConfig(); - if (config == null) { - return false; - } - return config.isLogEnabledForMethod(); - } - - public static boolean isLogEnabled() { - return isLogEnabled(DEFAULT_LOG_LEVEL); - } - - public static boolean isLogEnabled(int logLevel) { - return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel); - } - - @SuppressWarnings("unused") - public static Runnable decorateDebugRoot(Runnable runnable, String name, DebugConfig config) { - return runnable; - } - - @SuppressWarnings("unused") - public static <T> Callable<T> decorateDebugRoot(Callable<T> callable, String name, DebugConfig config) { - return callable; - } - - @SuppressWarnings("unused") - public static Runnable decorateScope(Runnable runnable, String name, Object... context) { - return runnable; - } - - @SuppressWarnings("unused") - public static <T> Callable<T> decorateScope(Callable<T> callable, String name, Object... context) { - return callable; - } - - /** - * Gets a string composed of the names in the current nesting of debug - * {@linkplain #scope(Object) scopes} separated by {@code '.'}. - */ - public static String currentScope() { - if (ENABLED) { - return DebugScope.getInstance().getQualifiedName(); - } else { - return ""; - } - } - - /** - * Represents a debug scope entered by {@link Debug#scope(Object)} or - * {@link Debug#sandbox(CharSequence, DebugConfig, Object...)}. Leaving the scope is achieved - * via {@link #close()}. - */ - public interface Scope extends AutoCloseable { - void close(); - } - - /** - * Creates and enters a new debug scope which will be a child of the current debug scope. - * <p> - * It is recommended to use the try-with-resource statement for managing entering and leaving - * debug scopes. For example: - * - * <pre> - * try (Scope s = Debug.scope("InliningGraph", inlineeGraph)) { - * ... - * } catch (Throwable e) { - * throw Debug.handle(e); - * } - * </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 contextObjects an array of object to be appended to the {@linkplain #context() - * current} debug context - * @throws Throwable used to enforce a catch block. - * @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[] contextObjects) throws Throwable { - if (ENABLED) { - return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, contextObjects); - } else { - return null; - } - } - - /** - * Similar to {@link #scope(Object, Object[])} but without context objects. Therefore the catch - * block can be omitted. - * - * @see #scope(Object, Object[]) - */ - public static Scope scope(Object name) { - if (ENABLED) { - return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null); - } else { - return null; - } - } - - /** - * @see #scope(Object, Object[]) - * @param context an object to be appended to the {@linkplain #context() current} debug context - */ - public static Scope scope(Object name, Object context) throws Throwable { - if (ENABLED) { - return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context); - } else { - return null; - } - } - - /** - * @see #scope(Object, 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) throws Throwable { - if (ENABLED) { - return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2); - } else { - return null; - } - } - - /** - * @see #scope(Object, 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) throws Throwable { - 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 - * debug scopes. For example: - * - * <pre> - * try (Scope s = Debug.sandbox("CompilingStub", null, stubGraph)) { - * ... - * } catch (Throwable e) { - * throw Debug.handle(e); - * } - * </pre> - * - * @param name the name of the new scope - * @param config the debug configuration to use for 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 sandbox(CharSequence name, DebugConfig config, Object... context) throws Throwable { - if (ENABLED) { - DebugConfig sandboxConfig = config == null ? silentConfig() : config; - return DebugScope.getInstance().scope(name, sandboxConfig, context); - } else { - return null; - } - } - - public static Scope forceLog() throws Throwable { - ArrayList<Object> context = new ArrayList<>(); - for (Object obj : context()) { - context.add(obj); - } - return Debug.sandbox("forceLog", new DelegatingDebugConfig().override(Level.LOG, Integer.MAX_VALUE).enable(LOG_METHOD), context.toArray()); - } - - /** - * Opens a scope in which exception {@linkplain DebugConfig#interceptException(Throwable) - * interception} is disabled. It is recommended to use the try-with-resource statement for - * managing entering and leaving such scopes: - * - * <pre> - * try (DebugConfigScope s = Debug.disableIntercept()) { - * ... - * } - * </pre> - * - * This is particularly useful to suppress extraneous output in JUnit tests that are expected to - * throw an exception. - */ - public static DebugConfigScope disableIntercept() { - return Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); - } - - /** - * 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(Object)} and - * {@link #sandbox(CharSequence, DebugConfig, Object...)} is used - * - * @see #scope(Object, Object[]) - * @see #sandbox(CharSequence, DebugConfig, Object...) - */ - public static RuntimeException handle(Throwable exception) { - if (ENABLED) { - return DebugScope.getInstance().handle(exception); - } else { - if (exception instanceof Error) { - throw (Error) exception; - } - if (exception instanceof RuntimeException) { - throw (RuntimeException) exception; - } - throw new RuntimeException(exception); - } - } - - public static void log(String msg) { - log(DEFAULT_LOG_LEVEL, msg); - } - - /** - * 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(int logLevel, String msg) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, msg); - } - } - - public static void log(String format, Object arg) { - log(DEFAULT_LOG_LEVEL, format, arg); - } - - /** - * Prints a message to the current debug scope's logging stream if logging is enabled. - * - * @param format a format string - * @param arg the argument referenced by the format specifiers in {@code format} - */ - public static void log(int logLevel, String format, Object arg) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg); - } - } - - public static void log(String format, int arg) { - log(DEFAULT_LOG_LEVEL, format, arg); - } - - /** - * Prints a message to the current debug scope's logging stream if logging is enabled. - * - * @param format a format string - * @param arg the argument referenced by the format specifiers in {@code format} - */ - public static void log(int logLevel, String format, int arg) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg); - } - } - - public static void log(String format, Object arg1, Object arg2) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2); - } - } - - public static void log(String format, int arg1, Object arg2) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, int arg1, Object arg2) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2); - } - } - - public static void log(String format, Object arg1, int arg2) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, int arg2) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2); - } - } - - public static void log(String format, int arg1, int arg2) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, int arg1, int arg2) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2); - } - } - - public static void log(String format, Object arg1, Object arg2, Object arg3) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); - } - } - - public static void log(String format, int arg1, int arg2, int arg3) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, int arg1, int arg2, int arg3) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); - } - } - - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4); - } - } - - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5); - } - } - - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - } - - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) { - log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - /** - * @see #log(int, String, Object) - */ - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - } - - public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) { - if (ENABLED) { - DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - } - - public static void logv(String format, Object... args) { - logv(DEFAULT_LOG_LEVEL, format, args); - } - - /** - * Prints a message to the current debug scope's logging stream. This method must only be called - * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call - * site. If possible, call one of the other {@code log()} methods in this class that take a - * fixed number of parameters. - * - * @param format a format string - * @param args the arguments referenced by the format specifiers in {@code format} - */ - public static void logv(int logLevel, 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(logLevel, format, args); - } - - /** - * This override exists to catch cases when {@link #log(String, Object)} is called with one - * argument bound to a varargs method parameter. It will bind to this method instead of the - * single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void log(String format, Object[] args) { - assert false : "shouldn't use this"; - log(DEFAULT_LOG_LEVEL, format, args); - } - - /** - * This override exists to catch cases when {@link #log(int, String, Object)} is called with one - * argument bound to a varargs method parameter. It will bind to this method instead of the - * single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void log(int logLevel, String format, Object[] args) { - assert false : "shouldn't use this"; - logv(logLevel, format, args); - } - - public static void dump(Object object, String msg) { - dump(DEFAULT_LOG_LEVEL, object, msg); - } - - public static void dump(int dumpLevel, Object object, String msg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { - DebugScope.getInstance().dump(dumpLevel, object, msg); - } - } - - public static void dump(Object object, String format, Object arg) { - dump(DEFAULT_LOG_LEVEL, object, format, arg); - } - - public static void dump(int dumpLevel, Object object, String format, Object arg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { - DebugScope.getInstance().dump(dumpLevel, object, format, arg); - } - } - - public static void dump(Object object, String format, Object arg1, Object arg2) { - dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2); - } - - public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { - DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2); - } - } - - public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) { - dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3); - } - - public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { - DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3); - } - } - - /** - * This override exists to catch cases when {@link #dump(Object, String, Object)} is called with - * one argument bound to a varargs method parameter. It will bind to this method instead of the - * single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void dump(Object object, String format, Object[] args) { - assert false : "shouldn't use this"; - dump(DEFAULT_LOG_LEVEL, object, format, args); - } - - /** - * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called - * with one argument bound to a varargs method parameter. It will bind to this method instead of - * the single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void dump(int dumpLevel, Object object, String format, Object[] args) { - assert false : "shouldn't use this"; - if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { - DebugScope.getInstance().dump(dumpLevel, object, format, args); - } - } - - /** - * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() - * config} to perform verification on a given object. - * - * @param object object to verify - * @param message description of verification context - * - * @see DebugVerifyHandler#verify(Object, String) - */ - public static void verify(Object object, String message) { - if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, message); - } - } - - /** - * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() - * config} to perform verification on a given object. - * - * @param object object to verify - * @param format a format string for the description of the verification context - * @param arg the argument referenced by the format specifiers in {@code format} - * - * @see DebugVerifyHandler#verify(Object, String) - */ - public static void verify(Object object, String format, Object arg) { - if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, format, arg); - } - } - - /** - * This override exists to catch cases when {@link #verify(Object, String, Object)} is called - * with one argument bound to a varargs method parameter. It will bind to this method instead of - * the single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void verify(Object object, String format, Object[] args) { - assert false : "shouldn't use this"; - if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, format, args); - } - } - - /** - * Opens a new indentation level (by adding some spaces) based on the current indentation level. - * This should be used in a {@linkplain Indent try-with-resources} pattern. - * - * @return an object that reverts to the current indentation level when - * {@linkplain Indent#close() closed} or null if debugging is disabled - * @see #logAndIndent(int, String) - * @see #logAndIndent(int, String, Object) - */ - public static Indent indent() { - if (ENABLED) { - DebugScope scope = DebugScope.getInstance(); - return scope.pushIndentLogger(); - } - return null; - } - - public static Indent logAndIndent(String msg) { - return logAndIndent(DEFAULT_LOG_LEVEL, msg); - } - - /** - * A convenience function which combines {@link #log(String)} and {@link #indent()}. - * - * @param msg the message to log - * @return an object that reverts to the current indentation level when - * {@linkplain Indent#close() closed} or null if debugging is disabled - */ - public static Indent logAndIndent(int logLevel, String msg) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, msg); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); - } - - /** - * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. - * - * @param format a format string - * @param arg the argument referenced by the format specifiers in {@code format} - * @return an object that reverts to the current indentation level when - * {@linkplain Indent#close() closed} or null if debugging is disabled - */ - public static Indent logAndIndent(int logLevel, String format, Object arg) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg); - } - return null; - } - - public static Indent logAndIndent(String format, int arg) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); - } - - /** - * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. - * - * @param format a format string - * @param arg the argument referenced by the format specifiers in {@code format} - * @return an object that reverts to the current indentation level when - * {@linkplain Indent#close() closed} or null if debugging is disabled - */ - public static Indent logAndIndent(int logLevel, String format, int arg) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg); - } - return null; - } - - public static Indent logAndIndent(String format, int arg1, Object arg2) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, int arg1, Object arg2) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, int arg2) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2); - } - return null; - } - - public static Indent logAndIndent(String format, int arg1, int arg2) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, Object arg2) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); - } - return null; - } - - public static Indent logAndIndent(String format, int arg1, int arg2, int arg3) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2, int arg3) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, int arg2, int arg3) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2, int arg3) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5); - } - return null; - } - - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { - return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - /** - * @see #logAndIndent(int, String, Object) - */ - public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { - if (ENABLED && Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - return null; - } - - /** - * A convenience function which combines {@link #logv(int, String, Object...)} and - * {@link #indent()}. - * - * @param format a format string - * @param args the arguments referenced by the format specifiers in {@code format} - * @return an object that reverts to the current indentation level when - * {@linkplain Indent#close() closed} or null if debugging is disabled - */ - public static Indent logvAndIndent(int logLevel, String format, Object... args) { - if (ENABLED) { - if (Debug.isLogEnabled(logLevel)) { - return logvAndIndentInternal(logLevel, format, args); - } - return null; - } - throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()"); - } - - private static Indent logvAndIndentInternal(int logLevel, String format, Object... args) { - assert ENABLED && Debug.isLogEnabled(logLevel) : "must have checked Debug.isLogEnabled()"; - DebugScope scope = DebugScope.getInstance(); - scope.log(logLevel, format, args); - return scope.pushIndentLogger(); - } - - /** - * This override exists to catch cases when {@link #logAndIndent(String, Object)} is called with - * one argument bound to a varargs method parameter. It will bind to this method instead of the - * single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void logAndIndent(String format, Object[] args) { - assert false : "shouldn't use this"; - logAndIndent(DEFAULT_LOG_LEVEL, format, args); - } - - /** - * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called - * with one argument bound to a varargs method parameter. It will bind to this method instead of - * the single arg variant and produce a deprecation warning instead of silently wrapping the - * Object[] inside of another Object[]. - */ - @Deprecated - public static void logAndIndent(int logLevel, String format, Object[] args) { - assert false : "shouldn't use this"; - logvAndIndent(logLevel, format, args); - } - - public static Iterable<Object> context() { - if (ENABLED) { - return DebugScope.getInstance().getCurrentContext(); - } else { - return Collections.emptyList(); - } - } - - @SuppressWarnings("unchecked") - public static <T> List<T> contextSnapshot(Class<T> clazz) { - if (ENABLED) { - List<T> result = new ArrayList<>(); - for (Object o : context()) { - if (clazz.isInstance(o)) { - result.add((T) o); - } - } - return result; - } else { - return Collections.emptyList(); - } - } - - /** - * Searches the current debug scope, bottom up, for a context object that is an instance of a - * given type. The first such object found is returned. - */ - @SuppressWarnings("unchecked") - public static <T> T contextLookup(Class<T> clazz) { - if (ENABLED) { - for (Object o : context()) { - if (clazz.isInstance(o)) { - return ((T) o); - } - } - } - return null; - } - - /** - * Creates a {@linkplain DebugMemUseTracker memory use tracker} that is enabled iff debugging is - * {@linkplain #isEnabled() enabled}. - * <p> - * A disabled tracker has virtually no overhead. - */ - public static DebugMemUseTracker memUseTracker(CharSequence name) { - if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { - return VOID_MEM_USE_TRACKER; - } - return createMemUseTracker("%s", name, null); - } - - /** - * Creates a debug memory use tracker. Invoking this method is equivalent to: - * - * <pre> - * Debug.memUseTracker(format, arg, null) - * </pre> - * - * except that the string formatting only happens if metering is enabled. - * - * @see #metric(String, Object, Object) - */ - public static DebugMemUseTracker memUseTracker(String format, Object arg) { - if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { - return VOID_MEM_USE_TRACKER; - } - return createMemUseTracker(format, arg, null); - } - - /** - * Creates a debug memory use tracker. Invoking this method is equivalent to: - * - * <pre> - * Debug.memUseTracker(String.format(format, arg1, arg2)) - * </pre> - * - * except that the string formatting only happens if memory use tracking is enabled. In - * addition, each argument is subject to the following type based conversion before being passed - * as an argument to {@link String#format(String, Object...)}: - * - * <pre> - * Type | Conversion - * ------------------+----------------- - * java.lang.Class | arg.getSimpleName() - * | - * </pre> - * - * @see #memUseTracker(CharSequence) - */ - public static DebugMemUseTracker memUseTracker(String format, Object arg1, Object arg2) { - if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) { - return VOID_MEM_USE_TRACKER; - } - return createMemUseTracker(format, arg1, arg2); - } - - private static DebugMemUseTracker createMemUseTracker(String format, Object arg1, Object arg2) { - String name = formatDebugName(format, arg1, arg2); - return new MemUseTrackerImpl(name, !isUnconditionalMemUseTrackingEnabled); - } - - /** - * Creates a {@linkplain DebugMetric metric} that is enabled iff debugging is - * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to - * {@value #ENABLE_METRIC_PROPERTY_NAME_PREFIX} to {@code name} is - * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the - * returned metric is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is - * conditional. - * <p> - * A disabled metric has virtually no overhead. - */ - public static DebugMetric metric(CharSequence name) { - if (!areUnconditionalMetricsEnabled() && !ENABLED) { - return VOID_METRIC; - } - return createMetric("%s", name, null); - } - - public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { - if (flags == 0 && width < 0) { - return s; - } - StringBuilder sb = new StringBuilder(s); - - // apply width and justification - int len = sb.length(); - if (len < width) { - for (int i = 0; i < width - len; i++) { - if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) { - sb.append(' '); - } else { - sb.insert(0, ' '); - } - } - } - - String res = sb.toString(); - if ((flags & UPPERCASE) == UPPERCASE) { - res = res.toUpperCase(); - } - return res; - } - - /** - * Creates a debug metric. Invoking this method is equivalent to: - * - * <pre> - * Debug.metric(format, arg, null) - * </pre> - * - * except that the string formatting only happens if metering is enabled. - * - * @see #metric(String, Object, Object) - */ - public static DebugMetric metric(String format, Object arg) { - if (!areUnconditionalMetricsEnabled() && !ENABLED) { - return VOID_METRIC; - } - return createMetric(format, arg, null); - } - - /** - * Creates a debug metric. Invoking this method is equivalent to: - * - * <pre> - * Debug.metric(String.format(format, arg1, arg2)) - * </pre> - * - * except that the string formatting only happens if metering is enabled. In addition, each - * argument is subject to the following type based conversion before being passed as an argument - * to {@link String#format(String, Object...)}: - * - * <pre> - * Type | Conversion - * ------------------+----------------- - * java.lang.Class | arg.getSimpleName() - * | - * </pre> - * - * @see #metric(CharSequence) - */ - public static DebugMetric metric(String format, Object arg1, Object arg2) { - if (!areUnconditionalMetricsEnabled() && !ENABLED) { - return VOID_METRIC; - } - return createMetric(format, arg1, arg2); - } - - private static DebugMetric createMetric(String format, Object arg1, Object arg2) { - String name = formatDebugName(format, arg1, arg2); - boolean conditional = enabledMetrics == null || !findMatch(enabledMetrics, enabledMetricsSubstrings, name); - if (!ENABLED && conditional) { - return VOID_METRIC; - } - return new MetricImpl(name, conditional); - } - - /** - * Changes the debug configuration for the current thread. - * - * @param config new configuration to use for the current thread - * @return an object that when {@linkplain DebugConfigScope#close() closed} will restore the - * debug configuration for the current thread to what it was before this method was - * called - */ - public static DebugConfigScope setConfig(DebugConfig config) { - if (ENABLED) { - return new DebugConfigScope(config); - } else { - return null; - } - } - - /** - * Creates an object for counting value frequencies. - */ - public static DebugHistogram createHistogram(String name) { - return new DebugHistogramImpl(name); - } - - public static DebugConfig silentConfig() { - return fixedConfig(0, 0, false, false, false, false, Collections.<DebugDumpHandler> emptyList(), Collections.<DebugVerifyHandler> emptyList(), null); - } - - public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, - final boolean isVerifyEnabled, final Collection<DebugDumpHandler> dumpHandlers, final Collection<DebugVerifyHandler> verifyHandlers, final PrintStream output) { - return new DebugConfig() { - - @Override - public int getLogLevel() { - return logLevel; - } - - public boolean isLogEnabledForMethod() { - return logLevel > 0; - } - - @Override - public boolean isMeterEnabled() { - return isMeterEnabled; - } - - @Override - public boolean isMemUseTrackingEnabled() { - return isMemUseTrackingEnabled; - } - - @Override - public int getDumpLevel() { - return dumpLevel; - } - - public boolean isDumpEnabledForMethod() { - return dumpLevel > 0; - } - - @Override - public boolean isVerifyEnabled() { - return isVerifyEnabled; - } - - public boolean isVerifyEnabledForMethod() { - return isVerifyEnabled; - } - - @Override - public boolean isTimeEnabled() { - return isTimerEnabled; - } - - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - - @Override - public Collection<DebugDumpHandler> dumpHandlers() { - return dumpHandlers; - } - - @Override - public Collection<DebugVerifyHandler> verifyHandlers() { - return verifyHandlers; - } - - @Override - public PrintStream output() { - return output; - } - - @Override - public void addToContext(Object o) { - } - - @Override - public void removeFromContext(Object o) { - } - }; - } - - private static final DebugMetric VOID_METRIC = new DebugMetric() { - - public void increment() { - } - - public void add(long value) { - } - - public void setConditional(boolean flag) { - throw new InternalError("Cannot make void metric conditional"); - } - - public boolean isConditional() { - return false; - } - - public long getCurrentValue() { - return 0L; - } - }; - - private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() { - - public DebugCloseable start() { - return DebugCloseable.VOID_CLOSEABLE; - } - - public long getCurrentValue() { - return 0; - } - }; - - public static final String ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME = "jvmci.debug.unscopedTimers"; - public static final String ENABLE_UNSCOPED_METRICS_PROPERTY_NAME = "jvmci.debug.unscopedMetrics"; - public static final String ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME = "jvmci.debug.unscopedMemUseTrackers"; - - /** - * @see #timer(CharSequence) - */ - public static final String ENABLE_TIMER_PROPERTY_NAME_PREFIX = "jvmci.debug.timer."; - - /** - * @see #metric(CharSequence) - */ - public static final String ENABLE_METRIC_PROPERTY_NAME_PREFIX = "jvmci.debug.metric."; - - /** - * Set of unconditionally enabled metrics. Possible values and their meanings: - * <ul> - * <li>{@code null}: no unconditionally enabled metrics</li> - * <li>{@code isEmpty()}: all metrics are unconditionally enabled</li> - * <li>{@code !isEmpty()}: use {@link #findMatch(Set, Set, String)} on this set and - * {@link #enabledMetricsSubstrings} to determine which metrics are unconditionally enabled</li> - * </ul> - */ - private static final Set<String> enabledMetrics; - - /** - * Set of unconditionally enabled timers. Same interpretation of values as for - * {@link #enabledMetrics}. - */ - private static final Set<String> enabledTimers; - - private static final Set<String> enabledMetricsSubstrings = new HashSet<>(); - private static final Set<String> enabledTimersSubstrings = new HashSet<>(); - - /** - * Specifies if all mem use trackers are unconditionally enabled. - */ - private static final boolean isUnconditionalMemUseTrackingEnabled; - - static { - Set<String> metrics = new HashSet<>(); - Set<String> timers = new HashSet<>(); - parseMetricAndTimerSystemProperties(metrics, timers, enabledMetricsSubstrings, enabledTimersSubstrings); - metrics = metrics.isEmpty() && enabledMetricsSubstrings.isEmpty() ? null : metrics; - timers = timers.isEmpty() && enabledTimersSubstrings.isEmpty() ? null : timers; - if (metrics == null && Boolean.getBoolean(ENABLE_UNSCOPED_METRICS_PROPERTY_NAME)) { - metrics = Collections.emptySet(); - } - if (timers == null && Boolean.getBoolean(ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME)) { - timers = Collections.emptySet(); - } - enabledMetrics = metrics; - enabledTimers = timers; - isUnconditionalMemUseTrackingEnabled = Boolean.getBoolean(ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME); - } - - private static boolean findMatch(Set<String> haystack, Set<String> haystackSubstrings, String needle) { - if (haystack.isEmpty()) { - // Empty haystack means match all - return true; - } - if (haystack.contains(needle)) { - return true; - } - if (!haystackSubstrings.isEmpty()) { - for (String h : haystackSubstrings) { - if (needle.startsWith(h)) { - return true; - } - } - } - return false; - } - - public static boolean areUnconditionalTimersEnabled() { - return enabledTimers != null; - } - - public static boolean areUnconditionalMetricsEnabled() { - return enabledMetrics != null; - } - - protected static void parseMetricAndTimerSystemProperties(Set<String> metrics, Set<String> timers, Set<String> metricsSubstrings, Set<String> timersSubstrings) { - do { - try { - for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) { - String name = e.getKey().toString(); - if (name.startsWith(ENABLE_METRIC_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { - if (name.endsWith("*")) { - metricsSubstrings.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length(), name.length() - 1)); - } else { - metrics.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length())); - } - } - if (name.startsWith(ENABLE_TIMER_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { - if (name.endsWith("*")) { - timersSubstrings.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length(), name.length() - 1)); - } else { - timers.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length())); - } - } - } - return; - } catch (ConcurrentModificationException e) { - // Iterating over the system properties may race with another thread that is - // updating the system properties. Simply try again in this case. - } - } while (true); - } - - /** - * Creates a {@linkplain DebugTimer timer} that is enabled iff debugging is - * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to - * {@value #ENABLE_TIMER_PROPERTY_NAME_PREFIX} to {@code name} is - * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the - * returned timer is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is - * conditional. - * <p> - * A disabled timer has virtually no overhead. - */ - public static DebugTimer timer(CharSequence name) { - if (!areUnconditionalTimersEnabled() && !ENABLED) { - return VOID_TIMER; - } - return createTimer("%s", name, null); - } - - /** - * Creates a debug timer. Invoking this method is equivalent to: - * - * <pre> - * Debug.timer(format, arg, null) - * </pre> - * - * except that the string formatting only happens if timing is enabled. - * - * @see #timer(String, Object, Object) - */ - public static DebugTimer timer(String format, Object arg) { - if (!areUnconditionalTimersEnabled() && !ENABLED) { - return VOID_TIMER; - } - return createTimer(format, arg, null); - } - - /** - * Creates a debug timer. Invoking this method is equivalent to: - * - * <pre> - * Debug.timer(String.format(format, arg1, arg2)) - * </pre> - * - * except that the string formatting only happens if timing is enabled. In addition, each - * argument is subject to the following type based conversion before being passed as an argument - * to {@link String#format(String, Object...)}: - * - * <pre> - * Type | Conversion - * ------------------+----------------- - * java.lang.Class | arg.getSimpleName() - * | - * </pre> - * - * @see #timer(CharSequence) - */ - public static DebugTimer timer(String format, Object arg1, Object arg2) { - if (!areUnconditionalTimersEnabled() && !ENABLED) { - return VOID_TIMER; - } - return createTimer(format, arg1, arg2); - } - - /** - * There are paths where construction of formatted class names are common and the code below is - * surprisingly expensive, so compute it once and cache it. - */ - private static final ClassValue<String> formattedClassName = new ClassValue<String>() { - @Override - protected String computeValue(Class<?> c) { - final String simpleName = c.getSimpleName(); - Class<?> enclosingClass = c.getEnclosingClass(); - if (enclosingClass != null) { - String prefix = ""; - while (enclosingClass != null) { - prefix = enclosingClass.getSimpleName() + "_" + prefix; - enclosingClass = enclosingClass.getEnclosingClass(); - } - return prefix + simpleName; - } else { - return simpleName; - } - } - }; - - public static Object convertFormatArg(Object arg) { - if (arg instanceof Class) { - return formattedClassName.get((Class<?>) arg); - } - return arg; - } - - private static String formatDebugName(String format, Object arg1, Object arg2) { - return String.format(format, convertFormatArg(arg1), convertFormatArg(arg2)); - } - - private static DebugTimer createTimer(String format, Object arg1, Object arg2) { - String name = formatDebugName(format, arg1, arg2); - boolean conditional = enabledTimers == null || !findMatch(enabledTimers, enabledTimersSubstrings, name); - if (!ENABLED && conditional) { - return VOID_TIMER; - } - return new TimerImpl(name, conditional); - } - - private static final DebugTimer VOID_TIMER = new DebugTimer() { - - public DebugCloseable start() { - return DebugCloseable.VOID_CLOSEABLE; - } - - public void setConditional(boolean flag) { - throw new InternalError("Cannot make void timer conditional"); - } - - public boolean isConditional() { - return false; - } - - public long getCurrentValue() { - return 0L; - } - - public TimeUnit getTimeUnit() { - return null; - } - }; -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugCloseable.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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 jdk.internal.jvmci.debug; - -/** - * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and - * adds the elapsed time since {@code start()} to the total for the timer. - */ -public interface DebugCloseable extends AutoCloseable { - - DebugCloseable VOID_CLOSEABLE = new DebugCloseable() { - - @Override - public void close() { - } - }; - - void close(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfig.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.io.*; -import java.util.*; - -public interface DebugConfig { - - /** - * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope} - * . - */ - int getLogLevel(); - - /** - * Determines the current dump level in the {@linkplain Debug#currentScope() current debug - * scope}. - */ - int getDumpLevel(); - - /** - * Determines if logging can be enabled in the current method, regardless of the - * {@linkplain Debug#currentScope() current debug scope}. - */ - boolean isLogEnabledForMethod(); - - /** - * Determines if metering is enabled in the {@linkplain Debug#currentScope() current debug - * scope}. - * - * @see Debug#metric(CharSequence) - */ - boolean isMeterEnabled(); - - /** - * Determines if memory use tracking is enabled in the {@linkplain Debug#currentScope() current - * debug scope}. - * - * @see Debug#memUseTracker(CharSequence) - */ - boolean isMemUseTrackingEnabled(); - - /** - * Determines if dumping can be enabled in the current method, regardless of the - * {@linkplain Debug#currentScope() current debug scope}. - */ - boolean isDumpEnabledForMethod(); - - /** - * @see Debug#isVerifyEnabled() - */ - boolean isVerifyEnabled(); - - /** - * @see Debug#isVerifyEnabledForMethod() - */ - boolean isVerifyEnabledForMethod(); - - /** - * Adds an object the context used by this configuration to do filtering. - */ - void addToContext(Object o); - - /** - * Removes an object the context used by this configuration to do filtering. - * - * This should only removes extra context added by {@link #addToContext(Object)}. - */ - void removeFromContext(Object o); - - /** - * @see Debug#timer(CharSequence) - */ - boolean isTimeEnabled(); - - /** - * Handles notification of an exception occurring within a debug scope. - * - * @return the exception object that is to be propagated to parent scope. A value of - * {@code null} indicates that {@code e} is to be propagated. - */ - RuntimeException interceptException(Throwable e); - - /** - * Gets the modifiable collection of dump handlers registered with this configuration. - */ - Collection<DebugDumpHandler> dumpHandlers(); - - PrintStream output(); - - /** - * Gets the modifiable collection of verify handlers registered with this configuration. - */ - Collection<DebugVerifyHandler> verifyHandlers(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfigCustomizer.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug; - -public interface DebugConfigCustomizer { - void customize(DebugConfig config); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugConfigScope.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import jdk.internal.jvmci.debug.internal.*; - -/** - * A utility for scoping a change to the current debug - * {@linkplain DebugScope#setConfig(DebugConfig) configuration}. For example: - * - * <pre> - * DebugConfig config = ...; - * try (DebugConfigScope s = new DebugConfigScope(config)) { - * // ... - * } - * </pre> - */ -public class DebugConfigScope implements AutoCloseable { - - private final DebugConfig current; - - /** - * Sets the current debug {@linkplain DebugScope#setConfig(DebugConfig) configuration} to a - * given value and creates an object that when {@linkplain #close() closed} resets the - * configuration to the {@linkplain DebugScope#getConfig() current} configuration. - */ - public DebugConfigScope(DebugConfig config) { - this.current = DebugScope.getConfig(); - DebugScope.getInstance().setConfig(config); - } - - public void close() { - DebugScope.getInstance().setConfig(current); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugDumpHandler.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.io.*; - -public interface DebugDumpHandler extends Closeable { - - void dump(Object object, String message); - - /** - * Flushes and releases resources managed by this dump handler. A subsequent call to - * {@link #dump(Object, String)} will create and open new resources. That is, this method can be - * used to reset the handler. - */ - @Override - void close(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugDumpScope.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -public class DebugDumpScope { - - public final String name; - - /** - * Specifies if this scope decorates an inner scope. A hierarchical or tree representation of - * nested scopes may choose to represent a decorator scope at the same level as the scope it - * decorates. - */ - public final boolean decorator; - - public DebugDumpScope(String name) { - this(name, false); - } - - public DebugDumpScope(String name, boolean decorator) { - this.name = name; - this.decorator = decorator; - } - - @Override - public String toString() { - return "DebugDumpScope[" + name + "]"; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugEnvironment.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug; - -import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*; - -import java.io.*; -import java.util.*; - -import jdk.internal.jvmci.service.*; - -public class DebugEnvironment { - - public static JVMCIDebugConfig initialize(PrintStream log) { - - if (!Debug.isEnabled()) { - log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true"); - return null; - } - List<DebugDumpHandler> dumpHandlers = new ArrayList<>(); - List<DebugVerifyHandler> verifyHandlers = new ArrayList<>(); - JVMCIDebugConfig debugConfig = new JVMCIDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), Verify.getValue(), MethodFilter.getValue(), - log, dumpHandlers, verifyHandlers); - - for (DebugConfigCustomizer customizer : Services.load(DebugConfigCustomizer.class)) { - customizer.customize(debugConfig); - } - - Debug.setConfig(debugConfig); - return debugConfig; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugFilter.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.util.*; -import java.util.regex.*; - -import jdk.internal.jvmci.debug.internal.*; - -/** - * Implements the filter specified by the {@link JVMCIDebugConfig#Dump}, - * {@link JVMCIDebugConfig#Log}, {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} - * options. - * <p> - * These options enable the associated debug facility if their filter matches the - * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. For the {@link JVMCIDebugConfig#Dump} and {@link JVMCIDebugConfig#Log} options, the log - * or dump level is set. The {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} - * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} - * means enabled. - * <p> - * A filter is a list of comma-separated terms of the form {@code <pattern>[:<level>]}. - * {@code <pattern>} is interpreted as a glob pattern if it contains a "*" or "?" character. - * Otherwise, it is interpreted as a substring. If {@code <pattern>} is empty, it matches every - * scope. If {@code :<level>} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term - * {@code ~<pattern>} is a shorthand for {@code <pattern>:0} to disable a debug facility for a - * pattern. - * <p> - * The resulting log level of a scope is determined by the <em>last</em> matching term. If no term - * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log - * level of {@link Debug#DEFAULT_LOG_LEVEL}. - * - * <h2>Examples of filters</h2> - * - * <ul> - * <li>(empty string)<br> - * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - * <li> {@code :1}<br> - * Matches any scope with log level 1. - * - * <li> {@code *}<br> - * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - * <li> {@code CodeGen,CodeInstall}<br> - * Matches scopes containing "CodeGen" or "CodeInstall", both with log level - * {@link Debug#DEFAULT_LOG_LEVEL}. - * - * <li> {@code CodeGen:2,CodeInstall:1}<br> - * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1. - * - * <li> {@code :1,Dead:2}<br> - * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1. - * - * <li> {@code :1,Dead:0}<br> - * Matches all scopes with log level 1, except those containing "Dead". - * - * <li> {@code Code*}<br> - * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - * <li> {@code Code,~Dead}<br> - * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * </ul> - */ -final class DebugFilter { - - public static DebugFilter parse(String spec) { - if (spec == null) { - return null; - } - return new DebugFilter(spec.split(",")); - } - - private final Term[] terms; - - private DebugFilter(String[] terms) { - if (terms.length == 0) { - this.terms = null; - } else { - this.terms = new Term[terms.length]; - for (int i = 0; i < terms.length; i++) { - String t = terms[i]; - int idx = t.indexOf(':'); - - String pattern; - int level; - if (idx < 0) { - if (t.startsWith("~")) { - pattern = t.substring(1); - level = 0; - } else { - pattern = t; - level = Debug.DEFAULT_LOG_LEVEL; - } - } else { - pattern = t.substring(0, idx); - if (idx + 1 < t.length()) { - level = Integer.parseInt(t.substring(idx + 1)); - } else { - level = Debug.DEFAULT_LOG_LEVEL; - } - } - - this.terms[i] = new Term(pattern, level); - } - } - } - - /** - * Check whether a given input is matched by this filter, and determine the log level. - */ - public int matchLevel(String input) { - if (terms == null) { - return Debug.DEFAULT_LOG_LEVEL; - } else { - int level = 0; - for (Term t : terms) { - if (t.matches(input)) { - level = t.level; - } - } - return level; - } - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder("DebugFilter"); - if (terms != null) { - buf.append(Arrays.toString(terms)); - } else { - buf.append("[]"); - } - return buf.toString(); - } - - private static class Term { - - private final Pattern pattern; - public final int level; - - public Term(String filter, int level) { - this.level = level; - if (filter.isEmpty()) { - this.pattern = null; - } else if (filter.contains("*") || filter.contains("?")) { - this.pattern = Pattern.compile(MethodFilter.createGlobString(filter)); - } else { - this.pattern = Pattern.compile(".*" + MethodFilter.createGlobString(filter) + ".*"); - } - } - - /** - * Determines if a given input is matched by this filter. - */ - public boolean matches(String input) { - return pattern == null || pattern.matcher(input).matches(); - } - - @Override - public String toString() { - return (pattern == null ? ".*" : pattern.toString()) + ":" + level; - } - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugHistogram.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug; - -import java.util.*; - -/** - * Facility for recording value frequencies. - */ -public interface DebugHistogram { - - /** - * Gets the name specified when this objected was {@linkplain Debug#createHistogram(String) - * created}. - */ - String getName(); - - /** - * Increments the count for a given value. - */ - void add(Object value); - - void add(Object value, long count); - - /** - * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places - * values with higher frequencies first. - */ - public class CountedValue implements Comparable<CountedValue> { - - private long count; - private final Object value; - - public CountedValue(long 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(long n) { - count += n; - } - - public long getCount() { - return count; - } - - public Object getValue() { - return value; - } - } - - /** - * Gets a list of the counted values, sorted in descending order of frequency. - */ - List<CountedValue> getValues(); - - /** - * Interface for a service that can render a visualization of a histogram. - */ - public interface Printer { - - void print(DebugHistogram histogram); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugInitializationPropertyProvider.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug; - -/** - * Sets one or more system properties used during initialization of the {@link Debug} class. - */ -public interface DebugInitializationPropertyProvider { - void apply(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugMemUseTracker.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import com.sun.management.*; - -/** - * Tracks memory usage within a scope using {@link ThreadMXBean}. This facility should be employed - * using the try-with-resources pattern: - * - * <pre> - * try (DebugMemUseTracker.Closeable a = memUseTracker.start()) { - * // the code to measure - * } - * </pre> - */ -public interface DebugMemUseTracker { - - /** - * Creates a point from which memory usage will be recorded if memory use tracking is - * {@linkplain Debug#isMemUseTrackingEnabled() enabled}. - * - * @return an object that must be closed once the activity has completed to add the memory used - * since this call to the total for this tracker - */ - DebugCloseable start(); - - /** - * Gets the current value of this tracker. - */ - long getCurrentValue(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugMetric.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -/** - * A counter for some value of interest. - */ -public interface DebugMetric { - - /** - * Adds 1 to this counter if metering is {@link Debug#isMeterEnabled() enabled} or this is an - * {@linkplain #isConditional() unconditional} metric. - */ - void increment(); - - /** - * Adds {@code value} to this counter if metering is {@link Debug#isMeterEnabled() enabled} or - * this is an {@linkplain #isConditional() unconditional} metric. - */ - void add(long value); - - /** - * Sets a flag determining if this counter is only enabled if metering is - * {@link Debug#isMeterEnabled() enabled}. - */ - void setConditional(boolean flag); - - /** - * Determines if this counter is only enabled if metering is {@link Debug#isMeterEnabled() - * enabled}. - */ - boolean isConditional(); - - /** - * Gets the current value of this metric. - */ - long getCurrentValue(); - - /** - * Determines if this counter is enabled (either conditionally or unconditionally). - */ - default boolean isEnabled() { - return !isConditional() || Debug.isMeterEnabled(); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugTimer.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.util.concurrent.*; - -/** - * A timer for some activity of interest. A timer should be deployed using the try-with-resources - * pattern: - * - * <pre> - * try (TimerCloseable a = timer.start()) { - * // the code to time - * } - * </pre> - */ -public interface DebugTimer { - - /** - * Starts this timer if timing is {@linkplain Debug#isTimeEnabled() enabled} or this is an - * {@linkplain #isConditional() unconditional} timer. - * - * @return an object that must be closed once the activity has completed to add the elapsed time - * since this call to the total for this timer - */ - DebugCloseable start(); - - /** - * Sets a flag determining if this timer is only enabled if timing is - * {@link Debug#isTimeEnabled() enabled}. - */ - void setConditional(boolean flag); - - /** - * Determines if this timer is only enabled if timing is {@link Debug#isTimeEnabled() enabled}. - */ - boolean isConditional(); - - /** - * Gets the current value of this timer. - */ - long getCurrentValue(); - - /** - * Gets the time unit of this timer. - */ - TimeUnit getTimeUnit(); - - /** - * Gets the timer recording the amount time spent within a timed scope minus the time spent in - * any nested timed scopes. - * - * @return null if this timer does not support flat timing - */ - default DebugTimer getFlat() { - return null; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DebugVerifyHandler.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -/** - * Performs some kind of verification on an object. - */ -public interface DebugVerifyHandler { - - /** - * Verifies that a given object satisfies some invariants. - * - * @param object object to verify - * @param message description of verification context - */ - void verify(Object object, String message); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/DelegatingDebugConfig.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug; - -import java.io.*; -import java.util.*; - -import jdk.internal.jvmci.debug.internal.*; - -public class DelegatingDebugConfig implements DebugConfig { - - protected final DebugConfig delegate; - - /** - * The features of a {@link DelegatingDebugConfig} that can be force - * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/ - * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or - * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}. - */ - public enum Feature { - /** - * @see Debug#isLogEnabledForMethod() - */ - LOG_METHOD, - /** - * @see Debug#isDumpEnabledForMethod() - */ - DUMP_METHOD, - /** - * @see Debug#isVerifyEnabled() - */ - VERIFY, - /** - * @see Debug#isVerifyEnabledForMethod() - */ - VERIFY_METHOD, - /** - * @see Debug#isMeterEnabled() - */ - METER, - /** - * @see Debug#isMemUseTrackingEnabled() - */ - TRACK_MEM_USE, - /** - * @see Debug#isTimeEnabled() - */ - TIME, - /** - * @see DebugConfig#interceptException(Throwable) - */ - INTERCEPT - } - - private final Map<Feature, Boolean> featureState = new EnumMap<>(Feature.class); - - /** - * The debug levels of a {@link DelegatingDebugConfig} than can be - * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or - * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}. - */ - public enum Level { - LOG, - DUMP - } - - private final Map<Level, Integer> levelState = new EnumMap<>(Level.class); - - /** - * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. - */ - public DelegatingDebugConfig() { - this(DebugScope.getConfig()); - } - - /** - * Creates a config that delegates to a given config. - */ - public DelegatingDebugConfig(DebugConfig delegate) { - this.delegate = delegate; - } - - public DelegatingDebugConfig enable(Feature feature) { - featureState.put(feature, Boolean.TRUE); - return this; - } - - public DelegatingDebugConfig disable(Feature feature) { - featureState.put(feature, Boolean.FALSE); - return this; - } - - public DelegatingDebugConfig override(Level level, int newLevel) { - levelState.put(level, newLevel); - return this; - } - - public DelegatingDebugConfig delegate(Feature feature) { - featureState.put(feature, null); - return this; - } - - public DelegatingDebugConfig delegate(Level level) { - levelState.put(level, null); - return this; - } - - @Override - public int getLogLevel() { - Integer ls = levelState.get(Level.LOG); - if (ls == null) { - return delegate.getLogLevel(); - } - return ls.intValue(); - } - - public boolean isLogEnabledForMethod() { - Boolean fs = featureState.get(Feature.LOG_METHOD); - if (fs == null) { - return delegate.isLogEnabledForMethod(); - } - return fs.booleanValue(); - } - - @Override - public boolean isMeterEnabled() { - Boolean fs = featureState.get(Feature.METER); - if (fs == null) { - return delegate.isMeterEnabled(); - } - return fs.booleanValue(); - } - - public boolean isMemUseTrackingEnabled() { - Boolean fs = featureState.get(Feature.TRACK_MEM_USE); - if (fs == null) { - return delegate.isMemUseTrackingEnabled(); - } - return fs.booleanValue(); - } - - @Override - public int getDumpLevel() { - Integer ls = levelState.get(Level.DUMP); - if (ls == null) { - return delegate.getDumpLevel(); - } - return ls.intValue(); - } - - public boolean isDumpEnabledForMethod() { - Boolean fs = featureState.get(Feature.DUMP_METHOD); - if (fs == null) { - return delegate.isDumpEnabledForMethod(); - } - return fs.booleanValue(); - } - - @Override - public boolean isVerifyEnabled() { - Boolean fs = featureState.get(Feature.VERIFY); - if (fs == null) { - return delegate.isVerifyEnabled(); - } - return fs.booleanValue(); - } - - public boolean isVerifyEnabledForMethod() { - Boolean fs = featureState.get(Feature.VERIFY_METHOD); - if (fs == null) { - return delegate.isVerifyEnabledForMethod(); - } - return fs.booleanValue(); - } - - @Override - public boolean isTimeEnabled() { - Boolean fs = featureState.get(Feature.TIME); - if (fs == null) { - return delegate.isTimeEnabled(); - } - return fs.booleanValue(); - } - - @Override - public RuntimeException interceptException(Throwable e) { - Boolean fs = featureState.get(Feature.INTERCEPT); - if (fs == null || fs) { - return delegate.interceptException(e); - } - return null; - } - - @Override - public Collection<DebugDumpHandler> dumpHandlers() { - return delegate.dumpHandlers(); - } - - @Override - public Collection<DebugVerifyHandler> verifyHandlers() { - return delegate.verifyHandlers(); - } - - @Override - public PrintStream output() { - return delegate.output(); - } - - @Override - public void addToContext(Object o) { - delegate.addToContext(o); - } - - @Override - public void removeFromContext(Object o) { - delegate.removeFromContext(o); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Fingerprint.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug; - -import java.util.*; -import java.util.stream.*; - -/** - * Facility for fingerprinting execution. - */ -public class Fingerprint implements AutoCloseable { - - public static final String ENABLED_PROPERTY_NAME = "jvmci.fingerprint"; - - /** - * Determines whether fingerprinting is enabled. This is set by the - * {@value #ENABLED_PROPERTY_NAME} system property when this class is initialized. - */ - public static final boolean ENABLED = Boolean.getBoolean(ENABLED_PROPERTY_NAME); - - private static final ThreadLocal<Fingerprint> current = ENABLED ? new ThreadLocal<>() : null; - - private final List<String> events; - private int index; - - /** - * Creates an object to record a fingerprint. - */ - public Fingerprint() { - events = new ArrayList<>(); - index = -1; - } - - /** - * Creates an object to verify execution matches a given fingerprint. - * - * @param toVerifyAgainst the fingerprint events to verify against - */ - public Fingerprint(List<String> toVerifyAgainst) { - this.events = toVerifyAgainst; - index = 0; - } - - /** - * Creates an object to verify execution matches a given fingerprint. - * - * @param toVerifyAgainst the fingerprint to verify against - */ - public Fingerprint(Fingerprint toVerifyAgainst) { - this(toVerifyAgainst.events); - } - - public Collection<String> getEvents() { - return Collections.unmodifiableCollection(events); - } - - /** - * Starts fingerprint recording or verification for the current thread. At most one fingerprint - * object can be active for any thread. - */ - public Fingerprint open() { - if (ENABLED) { - assert current.get() == null; - current.set(this); - return this; - } - return null; - } - - /** - * Finishes fingerprint recording or verification for the current thread. - */ - public void close() { - if (ENABLED) { - assert current.get() == this; - current.set(null); - } - } - - private static final int BREAKPOINT_EVENT = Integer.getInteger(ENABLED_PROPERTY_NAME + ".breakpointEvent", -1); - - /** - * Submits an execution event for the purpose of recording or verifying a fingerprint. This must - * only be called if {@link #ENABLED} is {@code true}. - */ - public static void submit(String format, Object... args) { - assert ENABLED : "fingerprinting must be enabled (-D" + ENABLED_PROPERTY_NAME + "=true)"; - Fingerprint fingerprint = current.get(); - if (fingerprint != null) { - int eventId = fingerprint.nextEventId(); - if (eventId == BREAKPOINT_EVENT) { - // Set IDE breakpoint on the following line and set the relevant - // system property to debug a fingerprint verification error. - System.console(); - } - fingerprint.event(String.format(eventId + ": " + format, args)); - } - } - - private int nextEventId() { - return index == -1 ? events.size() : index; - } - - private static final int MAX_EVENT_TAIL_IN_ERROR_MESSAGE = Integer.getInteger("jvmci.fingerprint.errorEventTailLength", 50); - - private String tail() { - int start = Math.max(index - MAX_EVENT_TAIL_IN_ERROR_MESSAGE, 0); - return events.subList(start, index).stream().collect(Collectors.joining(String.format("%n"))); - } - - private void event(String entry) { - if (index == -1) { - events.add(entry); - } else { - if (index > events.size()) { - throw new InternalError(String.format("%s%nOriginal fingerprint limit reached", tail())); - } - String l = events.get(index); - if (!l.equals(entry)) { - throw new InternalError(String.format("%s%nFingerprint differs at event %d%nexpected: %s%n actual: %s", tail(), index, l, entry)); - } - index++; - } - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Indent.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug; - -/** - * Object used to close a debug {@link Debug#indent() indentation} scope. - * <p> - * Example usage: - * - * <pre> - * - * try (Indent i1 = Debug.logAndIndent("header message")) { - * ... - * Debug.log("message"); - * ... - * try (Indent i2 = Debug.logAndIndent(sub-header message")) { - * ... - * Debug.log("inner message"); - * ... - * } - * } - * - * </pre> - */ -public interface Indent extends AutoCloseable { - - /** - * Closes the current indentation scope. - */ - void close(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/JVMCIDebugConfig.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,303 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.io.*; -import java.util.*; - -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.options.*; - -public class JVMCIDebugConfig implements DebugConfig { - @SuppressWarnings("all") - private static boolean assertionsEnabled() { - boolean assertionsEnabled = false; - assert assertionsEnabled = true; - return assertionsEnabled; - } - - // @formatter:off - @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) - public static final OptionValue<String> Dump = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all metrics unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> Meter = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) - public static final OptionValue<String> Verify = new OptionValue<String>() { - @Override - protected String defaultValue() { - return assertionsEnabled() ? "" : null; - } - }; - @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> TrackMemUse = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + - "An empty value enables all timers unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> Time = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) - public static final OptionValue<String> Log = new OptionValue<>(null); - @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) - public static final OptionValue<String> MethodFilter = new OptionValue<>(null); - @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) - public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false); - - @Option(help = "How to print metric and timing values:%n" + - "Name - aggregate by unqualified name%n" + - "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + - "Complete - aggregate by qualified name%n" + - "Thread - aggregate by qualified name and thread", type = OptionType.Debug) - public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); - @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) - public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); - @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) - public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null); - @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug) - public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); - @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) - public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false); - @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) - public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false); - // @formatter:on - - static boolean isNotEmpty(OptionValue<String> option) { - return option.getValue() != null && !option.getValue().isEmpty(); - } - - public static boolean areDebugScopePatternsEnabled() { - return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); - } - - /** - * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, - * non-empty value. - */ - public static boolean areScopedMetricsOrTimersEnabled() { - return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); - } - - private final DebugFilter logFilter; - private final DebugFilter meterFilter; - private final DebugFilter trackMemUseFilter; - private final DebugFilter timerFilter; - private final DebugFilter dumpFilter; - private final DebugFilter verifyFilter; - private final MethodFilter[] methodFilter; - private final List<DebugDumpHandler> dumpHandlers; - private final List<DebugVerifyHandler> verifyHandlers; - private final PrintStream output; - private final Set<Object> extraFilters = new HashSet<>(); - - public JVMCIDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, - List<DebugDumpHandler> dumpHandlers, List<DebugVerifyHandler> verifyHandlers) { - this.logFilter = DebugFilter.parse(logFilter); - this.meterFilter = DebugFilter.parse(meterFilter); - this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); - this.timerFilter = DebugFilter.parse(timerFilter); - this.dumpFilter = DebugFilter.parse(dumpFilter); - this.verifyFilter = DebugFilter.parse(verifyFilter); - if (methodFilter == null || methodFilter.isEmpty()) { - this.methodFilter = null; - } else { - this.methodFilter = jdk.internal.jvmci.debug.MethodFilter.parse(methodFilter); - } - - // Report the filters that have been configured so the user can verify it's what they expect - if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) { - // TTY.println(Thread.currentThread().getName() + ": " + toString()); - } - this.dumpHandlers = dumpHandlers; - this.verifyHandlers = verifyHandlers; - this.output = output; - } - - public int getLogLevel() { - return getLevel(logFilter); - } - - public boolean isLogEnabledForMethod() { - return isEnabledForMethod(logFilter); - } - - public boolean isMeterEnabled() { - return isEnabled(meterFilter); - } - - public boolean isMemUseTrackingEnabled() { - return isEnabled(trackMemUseFilter); - } - - public int getDumpLevel() { - return getLevel(dumpFilter); - } - - public boolean isDumpEnabledForMethod() { - return isEnabledForMethod(dumpFilter); - } - - public boolean isVerifyEnabled() { - return isEnabled(verifyFilter); - } - - public boolean isVerifyEnabledForMethod() { - return isEnabledForMethod(verifyFilter); - } - - public boolean isTimeEnabled() { - return isEnabled(timerFilter); - } - - public PrintStream output() { - return output; - } - - private boolean isEnabled(DebugFilter filter) { - return getLevel(filter) > 0; - } - - private int getLevel(DebugFilter filter) { - int level; - if (filter == null) { - level = 0; - } else { - level = filter.matchLevel(Debug.currentScope()); - } - if (level > 0 && !checkMethodFilter()) { - level = 0; - } - return level; - } - - private boolean isEnabledForMethod(DebugFilter filter) { - return filter != null && checkMethodFilter(); - } - - /** - * Extracts a {@link JavaMethod} from an opaque debug context. - * - * @return the {@link JavaMethod} represented by {@code context} or null - */ - public static JavaMethod asJavaMethod(Object context) { - if (context instanceof JavaMethodContex) { - return ((JavaMethodContex) context).asJavaMethod(); - } - return null; - } - - private boolean checkMethodFilter() { - if (methodFilter == null && extraFilters.isEmpty()) { - return true; - } else { - JavaMethod lastMethod = null; - for (Object o : Debug.context()) { - if (extraFilters.contains(o)) { - return true; - } else if (methodFilter != null) { - JavaMethod method = asJavaMethod(o); - if (method != null) { - if (!MethodFilterRootOnly.getValue()) { - if (jdk.internal.jvmci.debug.MethodFilter.matches(methodFilter, method)) { - return true; - } - } else { - /* - * The context values operate as a stack so if we want MethodFilter to - * only apply to the root method we have to check only the last method - * seen. - */ - lastMethod = method; - } - } - } - } - if (lastMethod != null && jdk.internal.jvmci.debug.MethodFilter.matches(methodFilter, lastMethod)) { - return true; - } - return false; - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Debug config:"); - add(sb, "Log", logFilter); - add(sb, "Meter", meterFilter); - add(sb, "Time", timerFilter); - add(sb, "Dump", dumpFilter); - add(sb, "MethodFilter", methodFilter); - return sb.toString(); - } - - private static void add(StringBuilder sb, String name, Object filter) { - if (filter != null) { - sb.append(' '); - sb.append(name); - sb.append('='); - if (filter instanceof Object[]) { - sb.append(Arrays.toString((Object[]) filter)); - } else { - sb.append(String.valueOf(filter)); - } - } - } - - @Override - public RuntimeException interceptException(Throwable e) { - if (e instanceof BailoutException && !InterceptBailout.getValue()) { - return null; - } - Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); - Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); - for (Object o : Debug.context()) { - if (DumpOnError.getValue()) { - Debug.dump(o, "Exception: " + e.toString()); - } else { - Debug.log("Context obj %s", o); - } - - } - return null; - } - - @Override - public Collection<DebugDumpHandler> dumpHandlers() { - return dumpHandlers; - } - - @Override - public Collection<DebugVerifyHandler> verifyHandlers() { - return verifyHandlers; - } - - @Override - public void addToContext(Object o) { - extraFilters.add(o); - } - - @Override - public void removeFromContext(Object o) { - extraFilters.remove(o); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/JavaMethodContex.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug; - -import jdk.internal.jvmci.meta.*; - -/** - * Interface for objects used in Debug {@linkplain Debug#context() context} that can provide a - * {@link JavaMethod}. - */ -public interface JavaMethodContex { - JavaMethod asJavaMethod(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Management.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/Management.java Fri Jul 24 02:11:18 2015 +0200 @@ -22,20 +22,38 @@ */ package jdk.internal.jvmci.debug; +import static java.lang.Thread.*; + import java.lang.management.*; import javax.management.*; public class Management { - public static ThreadMXBean getThreadMXBean() { + private static final com.sun.management.ThreadMXBean threadMXBean = Management.initThreadMXBean(); + + /** + * The amount of memory allocated by + * {@link com.sun.management.ThreadMXBean#getThreadAllocatedBytes(long)} itself. + */ + private static final long threadMXBeanOverhead = -getCurrentThreadAllocatedBytes() + getCurrentThreadAllocatedBytes(); + + public static long getCurrentThreadAllocatedBytes() { + return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead; + } + + private static com.sun.management.ThreadMXBean initThreadMXBean() { try { - return ManagementFactory.getThreadMXBean(); + return (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); } catch (Error err) { return new UnimplementedBean(); } } + public static ThreadMXBean getThreadMXBean() { + return threadMXBean; + } + private static class UnimplementedBean implements ThreadMXBean, com.sun.management.ThreadMXBean { public ObjectName getObjectName() {
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/MethodFilter.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug; - -import java.util.*; -import java.util.regex.*; - -import jdk.internal.jvmci.meta.*; - -/** - * This class implements a method filter that can filter based on class name, method name and - * parameters. The syntax for the source pattern that is passed to the constructor is as follows: - * - * <pre> - * SourcePatterns = SourcePattern ["," SourcePatterns] . - * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] . - * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" . - * Class = { package "." } class . - * </pre> - * - * - * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid - * filters are: - * - * <ul> - * <li> - * - * <pre> - * visit(Argument;BlockScope) - * </pre> - * - * Matches all methods named "visit", with the first parameter of type "Argument", and the second - * parameter of type "BlockScope". The packages of the parameter types are irrelevant.</li> - * <li> - * - * <pre> - * arraycopy(Object;;;;) - * </pre> - * - * Matches all methods named "arraycopy", with the first parameter of type "Object", and four more - * parameters of any type. The packages of the parameter types are irrelevant.</li> - * <li> - * - * <pre> - * com.oracle.graal.compiler.graph.PostOrderNodeIterator.* - * </pre> - * - * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".</li> - * <li> - * - * <pre> - * * - * </pre> - * - * Matches all methods in all classes</li> - * <li> - * - * <pre> - * com.oracle.graal.compiler.graph.*.visit - * </pre> - * - * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph". - * <li> - * - * <pre> - * arraycopy,toString - * </pre> - * - * Matches all methods named "arraycopy" or "toString", meaning that ',' acts as an <i>or</i> - * operator.</li> - * </ul> - */ -public class MethodFilter { - - private final Pattern clazz; - private final Pattern methodName; - private final Pattern[] signature; - - /** - * Parses a string containing list of comma separated filter patterns into an array of - * {@link MethodFilter}s. - */ - public static MethodFilter[] parse(String commaSeparatedPatterns) { - String[] filters = commaSeparatedPatterns.split(","); - MethodFilter[] methodFilters = new MethodFilter[filters.length]; - for (int i = 0; i < filters.length; i++) { - methodFilters[i] = new MethodFilter(filters[i]); - } - return methodFilters; - } - - /** - * Determines if a given method is matched by a given array of filters. - */ - public static boolean matches(MethodFilter[] filters, JavaMethod method) { - for (MethodFilter filter : filters) { - if (filter.matches(method)) { - return true; - } - } - return false; - } - - /** - * Determines if a given class name is matched by a given array of filters. - */ - public static boolean matchesClassName(MethodFilter[] filters, String className) { - for (MethodFilter filter : filters) { - if (filter.matchesClassName(className)) { - return true; - } - } - return false; - } - - public MethodFilter(String sourcePattern) { - String pattern = sourcePattern.trim(); - - // extract parameter part - int pos = pattern.indexOf('('); - if (pos != -1) { - if (pattern.charAt(pattern.length() - 1) != ')') { - throw new IllegalArgumentException("missing ')' at end of method filter pattern: " + pattern); - } - String[] signatureClasses = pattern.substring(pos + 1, pattern.length() - 1).split(";", -1); - signature = new Pattern[signatureClasses.length]; - for (int i = 0; i < signatureClasses.length; i++) { - signature[i] = createClassGlobPattern(signatureClasses[i].trim()); - } - pattern = pattern.substring(0, pos); - } else { - signature = null; - } - - // If there is at least one "." then everything before the last "." is the class name. - // Otherwise, the pattern contains only the method name. - pos = pattern.lastIndexOf('.'); - if (pos != -1) { - clazz = createClassGlobPattern(pattern.substring(0, pos)); - methodName = Pattern.compile(createGlobString(pattern.substring(pos + 1))); - } else { - clazz = null; - methodName = Pattern.compile(createGlobString(pattern)); - } - } - - static String createGlobString(String pattern) { - return Pattern.quote(pattern).replace("?", "\\E.\\Q").replace("*", "\\E.*\\Q"); - } - - private static Pattern createClassGlobPattern(String pattern) { - if (pattern.length() == 0) { - return null; - } else if (pattern.contains(".")) { - return Pattern.compile(createGlobString(pattern)); - } else { - return Pattern.compile("([^\\.\\$]*[\\.\\$])*" + createGlobString(pattern)); - } - } - - /** - * Determines if the class part of this filter matches a given class name. - */ - public boolean matchesClassName(String className) { - return clazz == null || clazz.matcher(className).matches(); - } - - public boolean matches(JavaMethod o) { - // check method name first, since MetaUtil.toJavaName is expensive - if (methodName != null && !methodName.matcher(o.getName()).matches()) { - return false; - } - if (clazz != null && !clazz.matcher(o.getDeclaringClass().toJavaName()).matches()) { - return false; - } - if (signature != null) { - Signature sig = o.getSignature(); - if (sig.getParameterCount(false) != signature.length) { - return false; - } - for (int i = 0; i < signature.length; i++) { - JavaType type = sig.getParameterType(i, null); - String javaName = type.toJavaName(); - if (signature[i] != null && !signature[i].matcher(javaName).matches()) { - return false; - } - } - } - return true; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder("MethodFilter["); - String sep = ""; - if (clazz != null) { - buf.append(sep).append("clazz=").append(clazz); - sep = ", "; - } - if (methodName != null) { - buf.append(sep).append("methodName=").append(methodName); - sep = ", "; - } - if (signature != null) { - buf.append(sep).append("signature=").append(Arrays.toString(signature)); - sep = ", "; - } - return buf.append("]").toString(); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/TopLevelDebugConfig.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 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 jdk.internal.jvmci.debug; - -/** - * A marker class for a scoped debug configuration covering a compilation region. Useful for - * programmatically enabling debug config features. - * - */ -public class TopLevelDebugConfig extends DelegatingDebugConfig { -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/AccumulatedDebugValue.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug.internal; - -public abstract class AccumulatedDebugValue extends DebugValue { - protected final DebugValue flat; - - public AccumulatedDebugValue(String name, boolean conditional, DebugValue flat) { - super(name + "_Accm", conditional); - this.flat = flat; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/CloseableCounterImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015, 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 jdk.internal.jvmci.debug.internal; - -import jdk.internal.jvmci.debug.*; - -/** - * A helper class for DebugValues that can nest and need to split out accumulated and flat values - * for some kind of counter-like measurement. - */ -abstract class CloseableCounterImpl implements DebugCloseable { - - protected final CloseableCounterImpl parent; - protected final AccumulatedDebugValue counter; - protected final long start; - protected long nestedAmountToSubtract; - - CloseableCounterImpl(CloseableCounterImpl parent, AccumulatedDebugValue counter) { - this.parent = parent; - this.start = getCounterValue(); - this.counter = counter; - } - - @Override - public void close() { - long end = getCounterValue(); - long difference = end - start; - if (parent != null) { - if (!counter.getName().equals(parent.counter.getName())) { - parent.nestedAmountToSubtract += difference; - - // Look for our counter in an outer scope and fix up - // the adjustment to the flat count - CloseableCounterImpl ancestor = parent.parent; - while (ancestor != null) { - if (ancestor.counter.getName().equals(counter.getName())) { - ancestor.nestedAmountToSubtract -= difference; - break; - } - ancestor = ancestor.parent; - } - } - } - long flatAmount = difference - nestedAmountToSubtract; - counter.addToCurrentValue(difference); - counter.flat.addToCurrentValue(flatAmount); - } - - abstract long getCounterValue(); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramAsciiPrinter.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug.internal; - -import java.io.*; -import java.util.*; - -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.debug.DebugHistogram.*; - -/** - * Renders a textual representation of a histogram to a given print stream. - */ -public class DebugHistogramAsciiPrinter implements Printer { - - public static final int NumberSize = 10; - public static final int DefaultNameSize = 50; - public static final int DefaultBarSize = 100; - public static final int DefaultScale = 1; - - private final PrintStream os; - private final int limit; - private final int nameSize; - private final int barSize; - private final int scale; - - public DebugHistogramAsciiPrinter(PrintStream os) { - this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize, DefaultScale); - } - - /** - * @param os where to print - * @param limit limits printing to the {@code limit} most frequent values - * @param nameSize the width of the value names column - * @param barSize the width of the value frequency column - * @param scale a factor by which every result is divided - */ - public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize, int scale) { - this.os = os; - this.limit = limit; - this.nameSize = nameSize; - this.barSize = barSize; - this.scale = scale; - } - - public void print(DebugHistogram histogram) { - List<CountedValue> list = histogram.getValues(); - if (list.isEmpty()) { - os.printf("%s is empty.%n", histogram.getName()); - return; - } - - // Sum up the total number of elements. - long total = list.stream().mapToLong(CountedValue::getCount).sum(); - - // Print header. - os.printf("%s has %d unique elements and %d total elements:%n", histogram.getName(), list.size(), total / scale); - - long max = list.get(0).getCount() / scale; - final int lineSize = nameSize + NumberSize + barSize + 10; - printLine(os, '-', 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); - long value = cv.getCount() / scale; - char[] bar = new char[(int) (((double) value / (double) max) * barSize)]; - Arrays.fill(bar, '='); - String objectString = String.valueOf(cv.getValue()); - if (objectString.length() > nameSize) { - objectString = objectString.substring(0, nameSize - 3) + "..."; - } - os.printf(formatString, objectString, value, new String(bar)); - } - printLine(os, '-', lineSize); - } - - 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)); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug.internal; - -import java.util.*; - -import jdk.internal.jvmci.debug.*; - -public class DebugHistogramImpl implements DebugHistogram { - - private final String name; - private HashMap<Object, CountedValue> map = new HashMap<>(); - - public DebugHistogramImpl(String name) { - this.name = name; - } - - public void add(Object value) { - CountedValue cv = map.get(value); - if (cv == null) { - map.put(value, new CountedValue(1, value)); - } else { - cv.inc(); - } - } - - public void add(Object value, long count) { - CountedValue cv = map.get(value); - if (cv == null) { - map.put(value, new CountedValue(count, value)); - } else { - cv.add(count); - } - } - - @Override - public String getName() { - return name; - } - - public List<CountedValue> getValues() { - ArrayList<CountedValue> res = new ArrayList<>(map.values()); - Collections.sort(res); - return res; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugHistogramRPrinter.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.debug.internal; - -import java.io.*; -import java.util.*; - -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.debug.DebugHistogram.*; - -/** - * Renders a histogram as an R script to a given print stream. The R script emitted for a histogram - * is a simple set of statements for defining a vector of named objects. - */ -public class DebugHistogramRPrinter implements Printer { - - private PrintStream os; - private int limit; - - public DebugHistogramRPrinter(PrintStream os) { - this(os, Integer.MAX_VALUE); - } - - /** - * @param os where to print - * @param limit limits printing to the {@code limit} most frequent values - */ - public DebugHistogramRPrinter(PrintStream os, int limit) { - this.os = os; - this.limit = limit; - } - - public void print(DebugHistogram histogram) { - List<CountedValue> list = histogram.getValues(); - if (list.isEmpty()) { - return; - } - - String var = histogram.getName().replace('-', '.').replace(' ', '_'); - os.print(var + " <- c("); - for (int i = 0; i < list.size() && i < limit; ++i) { - CountedValue cv = list.get(i); - if (i != 0) { - os.print(", "); - } - os.print(cv.getCount()); - } - os.println(");"); - - os.print("names(" + var + ") <- c("); - for (int i = 0; i < list.size() && i < limit; ++i) { - CountedValue cv = list.get(i); - if (i != 0) { - os.print(", "); - } - os.print("\"" + cv.getValue() + "\""); - } - os.println(");"); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugScope.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,487 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; - -import jdk.internal.jvmci.debug.*; - -public final class DebugScope implements Debug.Scope { - - private final class IndentImpl implements Indent { - - private static final String INDENTATION_INCREMENT = " "; - - final String indent; - final IndentImpl parentIndent; - - IndentImpl(IndentImpl parentIndent) { - this.parentIndent = parentIndent; - this.indent = (parentIndent == null ? "" : parentIndent.indent + INDENTATION_INCREMENT); - } - - private void printScopeName(StringBuilder str) { - if (logScopeName) { - if (parentIndent != null) { - parentIndent.printScopeName(str); - } - str.append(indent).append("[thread:").append(Thread.currentThread().getId()).append("] scope: ").append(getQualifiedName()).append(System.lineSeparator()); - logScopeName = false; - } - } - - public void log(int logLevel, String msg, Object... args) { - if (isLogEnabled(logLevel)) { - StringBuilder str = new StringBuilder(); - printScopeName(str); - str.append(indent); - String result = args.length == 0 ? msg : String.format(msg, args); - String lineSep = System.lineSeparator(); - str.append(result.replace(lineSep, lineSep.concat(indent))); - str.append(lineSep); - output.append(str); - lastUsedIndent = this; - } - } - - IndentImpl indent() { - lastUsedIndent = new IndentImpl(this); - return lastUsedIndent; - } - - @Override - public void close() { - if (parentIndent != null) { - lastUsedIndent = parentIndent; - } - } - } - - private static final ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>(); - private static final ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>(); - private static final ThreadLocal<DebugConfig> configTL = new ThreadLocal<>(); - private static final ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>(); - - private final DebugScope parent; - private final DebugConfig parentConfig; - private final boolean sandbox; - private IndentImpl lastUsedIndent; - private boolean logScopeName; - - private final Object[] context; - - private DebugValueMap valueMap; - - private String qualifiedName; - private final String unqualifiedName; - - private static final char SCOPE_SEP = '.'; - - private boolean meterEnabled; - private boolean timeEnabled; - private boolean memUseTrackingEnabled; - private boolean verifyEnabled; - - private int currentDumpLevel; - private int currentLogLevel; - - private PrintStream output; - - public static DebugScope getInstance() { - DebugScope result = instanceTL.get(); - if (result == null) { - DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread()); - instanceTL.set(topLevelDebugScope); - return topLevelDebugScope; - } else { - return result; - } - } - - public static DebugConfig getConfig() { - return configTL.get(); - } - - static final Object[] EMPTY_CONTEXT = new Object[0]; - - private DebugScope(Thread thread) { - this(thread.getName(), null, false); - computeValueMap(thread.getName()); - DebugValueMap.registerTopLevel(getValueMap()); - } - - private DebugScope(String unqualifiedName, DebugScope parent, boolean sandbox, Object... context) { - this.parent = parent; - this.sandbox = sandbox; - this.parentConfig = getConfig(); - this.context = context; - this.unqualifiedName = unqualifiedName; - if (parent != null) { - logScopeName = !unqualifiedName.equals(""); - } else { - logScopeName = true; - } - - this.output = TTY.out; - assert context != null; - } - - private void computeValueMap(String name) { - if (parent != null) { - for (DebugValueMap child : parent.getValueMap().getChildren()) { - if (child.getName().equals(name)) { - this.valueMap = child; - return; - } - } - this.valueMap = new DebugValueMap(name); - parent.getValueMap().addChild(this.valueMap); - } else { - this.valueMap = new DebugValueMap(name); - } - } - - public void close() { - instanceTL.set(parent); - configTL.set(parentConfig); - lastClosedTL.set(this); - } - - public boolean isDumpEnabled(int dumpLevel) { - assert dumpLevel > 0; - return currentDumpLevel >= dumpLevel; - } - - /** - * Enable dumping at the new {@code dumpLevel} for the remainder of enclosing scopes. This only - * works if a {@link TopLevelDebugConfig} was installed at a higher scope. - * - * @param dumpLevel - */ - public static void setDumpLevel(int dumpLevel) { - TopLevelDebugConfig config = fetchTopLevelDebugConfig("setDebugLevel"); - if (config != null) { - config.override(DelegatingDebugConfig.Level.DUMP, dumpLevel); - recursiveUpdateFlags(); - } - } - - /** - * Enable logging at the new {@code logLevel} for the remainder of enclosing scopes. This only - * works if a {@link TopLevelDebugConfig} was installed at a higher scope. - * - * @param logLevel - */ - public static void setLogLevel(int logLevel) { - TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel"); - if (config != null) { - config.override(DelegatingDebugConfig.Level.LOG, logLevel); - config.delegate(DelegatingDebugConfig.Feature.LOG_METHOD); - recursiveUpdateFlags(); - } - } - - private static void recursiveUpdateFlags() { - DebugScope c = DebugScope.getInstance(); - while (c != null) { - c.updateFlags(); - c = c.parent; - } - } - - private static TopLevelDebugConfig fetchTopLevelDebugConfig(String msg) { - DebugConfig config = getConfig(); - if (config instanceof TopLevelDebugConfig) { - return (TopLevelDebugConfig) config; - } else { - if (config == null) { - TTY.println("DebugScope.%s ignored because debugging is disabled", msg); - } else { - TTY.println("DebugScope.%s ignored because top level delegate config missing", msg); - } - return null; - } - } - - public boolean isVerifyEnabled() { - return verifyEnabled; - } - - public boolean isLogEnabled(int logLevel) { - assert logLevel > 0; - return currentLogLevel >= logLevel; - } - - public boolean isMeterEnabled() { - return meterEnabled; - } - - public boolean isTimeEnabled() { - return timeEnabled; - } - - public boolean isMemUseTrackingEnabled() { - return memUseTrackingEnabled; - } - - public void log(int logLevel, String msg, Object... args) { - if (isLogEnabled(logLevel)) { - getLastUsedIndent().log(logLevel, msg, args); - } - } - - public void dump(int dumpLevel, Object object, String formatString, Object... args) { - if (isDumpEnabled(dumpLevel)) { - DebugConfig config = getConfig(); - if (config != null) { - String message = String.format(formatString, args); - for (DebugDumpHandler dumpHandler : config.dumpHandlers()) { - dumpHandler.dump(object, message); - } - } - } - } - - /** - * This method exists mainly to allow a debugger (e.g., Eclipse) to force dump a graph. - */ - public static void forceDump(Object object, String format, Object... args) { - DebugConfig config = getConfig(); - if (config != null) { - String message = String.format(format, args); - for (DebugDumpHandler dumpHandler : config.dumpHandlers()) { - dumpHandler.dump(object, message); - } - } else { - TTY.println("Forced dump ignored because debugging is disabled - use -G:Dump=xxx option"); - } - } - - /** - * @see Debug#verify(Object, String) - */ - public void verify(Object object, String formatString, Object... args) { - if (isVerifyEnabled()) { - DebugConfig config = getConfig(); - if (config != null) { - String message = String.format(formatString, args); - for (DebugVerifyHandler handler : config.verifyHandlers()) { - handler.verify(object, message); - } - } - } - } - - /** - * Creates and enters a new debug scope which is either a child of the current scope or a - * disjoint top level scope. - * - * @param name the name of the new scope - * @param sandboxConfig the configuration to use for a new top level scope, or null if the new - * scope should be a child scope - * @param newContextObjects objects to be appended to the debug context - * @return the new scope which will be exited when its {@link #close()} method is called - */ - public DebugScope scope(CharSequence name, DebugConfig sandboxConfig, Object... newContextObjects) { - DebugScope newScope = null; - if (sandboxConfig != null) { - newScope = new DebugScope(name.toString(), this, true, newContextObjects); - configTL.set(sandboxConfig); - } else { - newScope = this.createChild(name.toString(), newContextObjects); - } - instanceTL.set(newScope); - newScope.updateFlags(); - return newScope; - } - - public RuntimeException handle(Throwable e) { - DebugScope lastClosed = lastClosedTL.get(); - assert lastClosed.parent == this : "Debug.handle() used with no matching Debug.scope(...) or Debug.sandbox(...)"; - if (e != lastExceptionThrownTL.get()) { - RuntimeException newException = null; - instanceTL.set(lastClosed); - try (DebugScope s = lastClosed) { - newException = s.interceptException(e); - } - assert instanceTL.get() == this; - assert lastClosed == lastClosedTL.get(); - if (newException == null) { - lastExceptionThrownTL.set(e); - } else { - lastExceptionThrownTL.set(newException); - throw newException; - } - } - if (e instanceof Error) { - throw (Error) e; - } - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } - throw new RuntimeException(e); - } - - private void updateFlags() { - DebugConfig config = getConfig(); - if (config == null) { - meterEnabled = false; - memUseTrackingEnabled = false; - timeEnabled = false; - verifyEnabled = false; - - currentDumpLevel = 0; - - // Be pragmatic: provide a default log stream to prevent a crash if the stream is not - // set while logging - output = TTY.out; - } else { - meterEnabled = config.isMeterEnabled(); - memUseTrackingEnabled = config.isMemUseTrackingEnabled(); - timeEnabled = config.isTimeEnabled(); - verifyEnabled = config.isVerifyEnabled(); - output = config.output(); - currentDumpLevel = config.getDumpLevel(); - currentLogLevel = config.getLogLevel(); - } - } - - private RuntimeException interceptException(final Throwable e) { - final DebugConfig config = getConfig(); - if (config != null) { - try (DebugScope s = scope("InterceptException", null, e)) { - return config.interceptException(e); - } catch (Throwable t) { - return new RuntimeException("Exception while intercepting exception", t); - } - } - return null; - } - - private DebugValueMap getValueMap() { - if (valueMap == null) { - computeValueMap(unqualifiedName); - } - return valueMap; - } - - long getCurrentValue(int index) { - return getValueMap().getCurrentValue(index); - } - - void setCurrentValue(int index, long l) { - getValueMap().setCurrentValue(index, l); - } - - private DebugScope createChild(String newName, Object[] newContext) { - return new DebugScope(newName, this, false, newContext); - } - - public Iterable<Object> getCurrentContext() { - final DebugScope scope = this; - return new Iterable<Object>() { - - @Override - public Iterator<Object> iterator() { - return new Iterator<Object>() { - - DebugScope currentScope = scope; - int objectIndex; - - @Override - public boolean hasNext() { - selectScope(); - return currentScope != null; - } - - private void selectScope() { - while (currentScope != null && currentScope.context.length <= objectIndex) { - currentScope = currentScope.sandbox ? null : currentScope.parent; - objectIndex = 0; - } - } - - @Override - public Object next() { - selectScope(); - if (currentScope != null) { - return currentScope.context[objectIndex++]; - } - throw new IllegalStateException("May only be called if there is a next element."); - } - - @Override - public void remove() { - throw new UnsupportedOperationException("This iterator is read only."); - } - }; - } - }; - } - - public static <T> T call(Callable<T> callable) { - try { - return callable.call(); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException(e); - } - } - } - - public void setConfig(DebugConfig newConfig) { - configTL.set(newConfig); - updateFlags(); - } - - public String getQualifiedName() { - if (qualifiedName == null) { - if (parent == null) { - qualifiedName = unqualifiedName; - } else { - qualifiedName = parent.getQualifiedName() + SCOPE_SEP + unqualifiedName; - } - } - return qualifiedName; - } - - public Indent pushIndentLogger() { - lastUsedIndent = getLastUsedIndent().indent(); - return lastUsedIndent; - } - - public IndentImpl getLastUsedIndent() { - if (lastUsedIndent == null) { - if (parent != null) { - lastUsedIndent = new IndentImpl(parent.getLastUsedIndent()); - } else { - lastUsedIndent = new IndentImpl(null); - } - } - return lastUsedIndent; - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugValue.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -/** - * A name and index for a value managed in a thread local value map. All access to the value is made - * via a {@link DebugValue} instance. - */ -public abstract class DebugValue implements Comparable<DebugValue> { - - private final String name; - private int index; - private boolean conditional; - - protected DebugValue(String name, boolean conditional) { - this.name = name; - this.index = -1; - this.conditional = conditional; - } - - public long getCurrentValue() { - ensureInitialized(); - return DebugScope.getInstance().getCurrentValue(index); - } - - protected void setCurrentValue(long l) { - ensureInitialized(); - DebugScope.getInstance().setCurrentValue(index, l); - } - - public void setConditional(boolean flag) { - conditional = flag; - } - - public boolean isConditional() { - return conditional; - } - - private void ensureInitialized() { - if (index == -1) { - index = KeyRegistry.register(this); - } - } - - protected void addToCurrentValue(long value) { - setCurrentValue(getCurrentValue() + value); - } - - /** - * Gets the globally unique index for the value represented by this object. - */ - public int getIndex() { - ensureInitialized(); - return index; - } - - /** - * Gets the globally unique name for the value represented by this object. - */ - public String getName() { - return name; - } - - public int compareTo(DebugValue o) { - return name.compareTo(o.name); - } - - @Override - public String toString() { - return name + "@" + index; - } - - public abstract String toString(long value); -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/DebugValueMap.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import java.util.*; - -/** - * A node in a tree of {@link DebugValue}s. - */ -public class DebugValueMap { - - private static final List<DebugValueMap> topLevelMaps = new ArrayList<>(); - - private long[] values; - private List<DebugValueMap> children; - private String name; - - public DebugValueMap(String name) { - this.name = name; - } - - public void setCurrentValue(int index, long l) { - ensureSize(index); - values[index] = l; - } - - public long getCurrentValue(int index) { - ensureSize(index); - return values[index]; - } - - public void clearChildren() { - if (children != null) { - children.clear(); - } - } - - public void reset() { - if (values != null) { - Arrays.fill(values, 0L); - } - if (children != null) { - for (DebugValueMap child : children) { - child.reset(); - } - } - } - - private void ensureSize(int index) { - if (values == null) { - values = new long[index + 1]; - } - if (values.length <= index) { - values = Arrays.copyOf(values, index + 1); - } - } - - private int capacity() { - return (values == null) ? 0 : values.length; - } - - public void addChild(DebugValueMap map) { - if (children == null) { - children = new ArrayList<>(4); - } - children.add(map); - } - - public List<DebugValueMap> getChildren() { - if (children == null) { - return Collections.emptyList(); - } else { - return Collections.unmodifiableList(children); - } - } - - public boolean hasChildren() { - return children != null && !children.isEmpty(); - } - - public String getName() { - return this.name; - } - - @Override - public String toString() { - return "DebugValueMap<" + getName() + ">"; - } - - public static synchronized void registerTopLevel(DebugValueMap map) { - topLevelMaps.add(map); - } - - public static synchronized List<DebugValueMap> getTopLevelMaps() { - return topLevelMaps; - } - - public void normalize() { - if (hasChildren()) { - Map<String, DebugValueMap> occurred = new HashMap<>(); - for (DebugValueMap map : children) { - String mapName = map.getName(); - if (!occurred.containsKey(mapName)) { - occurred.put(mapName, map); - map.normalize(); - } else { - occurred.get(mapName).mergeWith(map); - occurred.get(mapName).normalize(); - } - } - - if (occurred.values().size() < children.size()) { - // At least one duplicate was found. - children.clear(); - for (DebugValueMap map : occurred.values()) { - addChild(map); - map.normalize(); - } - } - } - } - - private void mergeWith(DebugValueMap map) { - if (map.hasChildren()) { - if (hasChildren()) { - children.addAll(map.children); - } else { - children = map.children; - } - map.children = null; - } - - int size = Math.max(this.capacity(), map.capacity()); - ensureSize(size); - for (int i = 0; i < size; ++i) { - long curValue = getCurrentValue(i); - long otherValue = map.getCurrentValue(i); - setCurrentValue(i, curValue + otherValue); - } - } - - public void group() { - if (this.hasChildren()) { - List<DebugValueMap> oldChildren = new ArrayList<>(this.children); - this.children.clear(); - for (DebugValueMap map : oldChildren) { - mergeWith(map); - } - } - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/KeyRegistry.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import java.util.*; - -/** - * Registry for allocating a globally unique integer id to each {@link DebugValue}. - */ -public class KeyRegistry { - - private static final Map<String, Integer> keyMap = new HashMap<>(); - private static final List<DebugValue> debugValues = new ArrayList<>(); - - /** - * Ensures a given debug value is registered. - * - * @return the globally unique id for {@code value} - */ - public static synchronized int register(DebugValue value) { - String name = value.getName(); - if (!keyMap.containsKey(name)) { - keyMap.put(name, debugValues.size()); - debugValues.add(value); - } - return keyMap.get(name); - } - - /** - * Gets a immutable view of the registered debug values. - * - * @return a list where {@code get(i).getIndex() == i} - */ - public static synchronized List<DebugValue> getDebugValues() { - return Collections.unmodifiableList(debugValues); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/MemUseTrackerImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import static java.lang.Thread.*; -import static jdk.internal.jvmci.debug.DebugCloseable.*; -import jdk.internal.jvmci.debug.*; - -import com.sun.management.*; - -public final class MemUseTrackerImpl extends AccumulatedDebugValue implements DebugMemUseTracker { - - private static final ThreadMXBean threadMXBean = (ThreadMXBean) Management.getThreadMXBean(); - - /** - * The amount of memory allocated by {@link ThreadMXBean#getThreadAllocatedBytes(long)} itself. - */ - private static final long threadMXBeanOverhead = -getCurrentThreadAllocatedBytes() + getCurrentThreadAllocatedBytes(); - - public static long getCurrentThreadAllocatedBytes() { - return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead; - } - - /** - * Records the most recent active tracker. - */ - private static final ThreadLocal<CloseableCounterImpl> currentTracker = new ThreadLocal<>(); - - public MemUseTrackerImpl(String name, boolean conditional) { - super(name, conditional, new DebugValue(name + "_Flat", conditional) { - - @Override - public String toString(long value) { - return valueToString(value); - } - }); - } - - @Override - public DebugCloseable start() { - if (!isConditional() || Debug.isMemUseTrackingEnabled()) { - MemUseCloseableCounterImpl result = new MemUseCloseableCounterImpl(this); - currentTracker.set(result); - return result; - } else { - return VOID_CLOSEABLE; - } - } - - public static String valueToString(long value) { - return String.format("%d bytes", value); - } - - @Override - public String toString(long value) { - return valueToString(value); - } - - private static final class MemUseCloseableCounterImpl extends CloseableCounterImpl implements DebugCloseable { - - private MemUseCloseableCounterImpl(AccumulatedDebugValue counter) { - super(currentTracker.get(), counter); - } - - @Override - long getCounterValue() { - return getCurrentThreadAllocatedBytes(); - } - - @Override - public void close() { - super.close(); - currentTracker.set(parent); - } - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/MetricImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import jdk.internal.jvmci.debug.*; - -public final class MetricImpl extends DebugValue implements DebugMetric { - - public MetricImpl(String name, boolean conditional) { - super(name, conditional); - if (isEnabled()) { - // Allows for zero-count metrics to be shown - getCurrentValue(); - } - } - - public void increment() { - add(1); - } - - public void add(long value) { - if (isEnabled()) { - super.addToCurrentValue(value); - } - } - - @Override - public String toString(long value) { - return Long.toString(value); - } -}
--- a/jvmci/jdk.internal.jvmci.debug/src/jdk/internal/jvmci/debug/internal/TimerImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * 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 jdk.internal.jvmci.debug.internal; - -import static jdk.internal.jvmci.debug.DebugCloseable.*; - -import java.lang.management.*; -import java.util.concurrent.*; - -import jdk.internal.jvmci.debug.*; - -public final class TimerImpl extends AccumulatedDebugValue implements DebugTimer { - - private static final ThreadMXBean threadMXBean = Management.getThreadMXBean(); - - /** - * Records the most recent active timer. - */ - private static final ThreadLocal<CloseableCounterImpl> currentTimer = new ThreadLocal<>(); - - static class FlatTimer extends DebugValue implements DebugTimer { - private TimerImpl accm; - - public FlatTimer(String name, boolean conditional) { - super(name + "_Flat", conditional); - } - - @Override - public String toString(long value) { - return valueToString(value); - } - - public TimeUnit getTimeUnit() { - return accm.getTimeUnit(); - } - - public DebugCloseable start() { - return accm.start(); - } - } - - public TimerImpl(String name, boolean conditional) { - super(name, conditional, new FlatTimer(name, conditional)); - ((FlatTimer) flat).accm = this; - } - - @Override - public DebugCloseable start() { - if (!isConditional() || Debug.isTimeEnabled()) { - AbstractTimer result; - if (threadMXBean.isCurrentThreadCpuTimeSupported()) { - result = new CpuTimeTimer(this); - } else { - result = new SystemNanosTimer(this); - } - currentTimer.set(result); - return result; - } else { - return VOID_CLOSEABLE; - } - } - - public static String valueToString(long value) { - return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10); - } - - public DebugTimer getFlat() { - return (FlatTimer) flat; - } - - @Override - public String toString(long value) { - return valueToString(value); - } - - public TimeUnit getTimeUnit() { - return TimeUnit.NANOSECONDS; - } - - private abstract static class AbstractTimer extends CloseableCounterImpl implements DebugCloseable { - - private AbstractTimer(AccumulatedDebugValue counter) { - super(currentTimer.get(), counter); - } - - @Override - public void close() { - super.close(); - currentTimer.set(parent); - } - } - - private final class SystemNanosTimer extends AbstractTimer { - - public SystemNanosTimer(TimerImpl timer) { - super(timer); - } - - @Override - protected long getCounterValue() { - return System.nanoTime(); - } - } - - private final class CpuTimeTimer extends AbstractTimer { - - public CpuTimeTimer(TimerImpl timer) { - super(timer); - } - - @Override - protected long getCounterValue() { - return threadMXBean.getCurrentThreadCpuTime(); - } - } -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilationStatistics.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/* - * 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 jdk.internal.jvmci.hotspot; - -import static java.lang.Thread.*; - -import java.io.*; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -import jdk.internal.jvmci.debug.*; - -import com.sun.management.*; - -@SuppressWarnings("unused") -public final class CompilationStatistics { - - private static final long RESOLUTION = 100000000; - private static final boolean ENABLED = Boolean.getBoolean("jvmci.comp.stats"); - - private static final CompilationStatistics DUMMY = new CompilationStatistics(null, false); - - private static ConcurrentLinkedDeque<CompilationStatistics> list = new ConcurrentLinkedDeque<>(); - - private static final ThreadLocal<Deque<CompilationStatistics>> current = new ThreadLocal<Deque<CompilationStatistics>>() { - - @Override - protected Deque<CompilationStatistics> initialValue() { - return new ArrayDeque<>(); - } - }; - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private static @interface NotReported { - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private static @interface TimeValue { - } - - private static long zeroTime = System.nanoTime(); - - private static long getThreadAllocatedBytes() { - ThreadMXBean thread = (ThreadMXBean) Management.getThreadMXBean(); - return thread.getThreadAllocatedBytes(currentThread().getId()); - } - - @NotReported private final long startTime; - @NotReported private long threadAllocatedBytesStart; - - private int bytecodeCount; - private int codeSize; - @TimeValue private long duration; - private long memoryUsed; - private final boolean osr; - private final String holder; - private final String name; - private final String signature; - - private CompilationStatistics(HotSpotResolvedJavaMethod method, boolean osr) { - this.osr = osr; - if (method != null) { - holder = method.getDeclaringClass().getName(); - name = method.getName(); - signature = method.getSignature().toMethodDescriptor(); - startTime = System.nanoTime(); - bytecodeCount = method.getCodeSize(); - threadAllocatedBytesStart = getThreadAllocatedBytes(); - } else { - holder = ""; - name = ""; - signature = ""; - startTime = 0; - } - } - - public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) { - if (ENABLED) { - duration = System.nanoTime() - startTime; - codeSize = (int) code.getCodeSize(); - memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart; - if (current.get().getLast() != this) { - throw new RuntimeException("mismatch in finish()"); - } - current.get().removeLast(); - } - } - - public static CompilationStatistics current() { - return current.get().isEmpty() ? null : current.get().getLast(); - } - - public static CompilationStatistics create(HotSpotResolvedJavaMethod method, boolean isOSR) { - if (ENABLED) { - CompilationStatistics stats = new CompilationStatistics(method, isOSR); - list.add(stats); - current.get().addLast(stats); - return stats; - } else { - return DUMMY; - } - } - - @SuppressWarnings("deprecation") - public static void clear(String dumpName) { - if (!ENABLED) { - return; - } - try { - ConcurrentLinkedDeque<CompilationStatistics> snapshot = list; - long snapshotZeroTime = zeroTime; - - list = new ConcurrentLinkedDeque<>(); - zeroTime = System.nanoTime(); - - Date now = new Date(); - String dateString = (now.getYear() + 1900) + "-" + (now.getMonth() + 1) + "-" + now.getDate() + "-" + now.getHours() + "" + now.getMinutes(); - - dumpCompilations(snapshot, dumpName, dateString); - - try (FileOutputStream fos = new FileOutputStream("timeline_" + dateString + "_" + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) { - - long[] timeSpent = new long[10000]; - int maxTick = 0; - for (CompilationStatistics stats : snapshot) { - long start = stats.startTime - snapshotZeroTime; - long duration = stats.duration; - if (start < 0) { - duration -= -start; - start = 0; - } - - int tick = (int) (start / RESOLUTION); - long timeLeft = RESOLUTION - (start % RESOLUTION); - - while (tick < timeSpent.length && duration > 0) { - if (tick > maxTick) { - maxTick = tick; - } - timeSpent[tick] += Math.min(timeLeft, duration); - duration -= timeLeft; - tick++; - timeLeft = RESOLUTION; - } - } - String timelineName = System.getProperty("stats.timeline.name"); - if (timelineName != null && !timelineName.isEmpty()) { - out.print(timelineName + "\t"); - } - for (int i = 0; i <= maxTick; i++) { - out.print((timeSpent[i] * 100 / RESOLUTION) + "\t"); - } - out.println(); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - protected static void dumpCompilations(ConcurrentLinkedDeque<CompilationStatistics> snapshot, String dumpName, String dateString) throws IllegalAccessException, FileNotFoundException { - String fileName = "compilations_" + dateString + "_" + dumpName + ".csv"; - try (PrintStream out = new PrintStream(fileName)) { - // output the list of all compilations - - Field[] declaredFields = CompilationStatistics.class.getDeclaredFields(); - ArrayList<Field> fields = new ArrayList<>(); - for (Field field : declaredFields) { - if (!Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(NotReported.class)) { - fields.add(field); - } - } - for (Field field : fields) { - out.print(field.getName() + "\t"); - } - out.println(); - for (CompilationStatistics stats : snapshot) { - for (Field field : fields) { - if (field.isAnnotationPresent(TimeValue.class)) { - double value = field.getLong(stats) / 1000000d; - out.print(String.format(Locale.ENGLISH, "%.3f", value) + "\t"); - } else { - out.print(field.get(stats) + "\t"); - } - } - out.println(); - } - } - } -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilationTask.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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 jdk.internal.jvmci.hotspot; - -import static jdk.internal.jvmci.common.UnsafeAccess.*; -import static jdk.internal.jvmci.compiler.Compiler.*; -import static jdk.internal.jvmci.debug.Debug.*; - -import java.util.concurrent.*; - -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.compiler.Compiler; -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.debug.Debug.Scope; -import jdk.internal.jvmci.debug.internal.*; -import jdk.internal.jvmci.hotspot.events.*; -import jdk.internal.jvmci.hotspot.events.EventProvider.CompilationEvent; -import jdk.internal.jvmci.hotspot.events.EventProvider.CompilerFailureEvent; -import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.service.*; - -//JaCoCo Exclude - -public class CompilationTask { - - private static final DebugMetric BAILOUTS = Debug.metric("Bailouts"); - - private static final EventProvider eventProvider; - static { - EventProvider provider = Services.loadSingle(EventProvider.class, false); - if (provider == null) { - eventProvider = new EmptyEventProvider(); - } else { - eventProvider = provider; - } - } - private static final Compiler compiler = Services.loadSingle(Compiler.class, true); - - private final HotSpotResolvedJavaMethod method; - private final int entryBCI; - private final int id; - - /** - * Specifies whether the compilation result is installed as the - * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method. - */ - private final boolean installAsDefault; - - static class Lazy { - /** - * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the - * current compiler thread, e.g. total allocated bytes. - */ - static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean(); - } - - /** - * The address of the JVMCIEnv associated with this compilation or 0L if no such object exists. - */ - private final long jvmciEnv; - - public CompilationTask(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id, boolean installAsDefault) { - this.method = method; - this.entryBCI = entryBCI; - this.id = id; - this.jvmciEnv = jvmciEnv; - this.installAsDefault = installAsDefault; - } - - public ResolvedJavaMethod getMethod() { - return method; - } - - /** - * Returns the compilation id of this task. - * - * @return compile id - */ - public int getId() { - return id; - } - - public int getEntryBCI() { - return entryBCI; - } - - /** - * Time spent in compilation. - */ - private static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); - - /** - * Meters the {@linkplain CompilationResult#getBytecodeSize() bytecodes} compiled. - */ - private static final DebugMetric CompiledBytecodes = Debug.metric("CompiledBytecodes"); - - public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); - - public void runCompilation() { - HotSpotVMConfig config = HotSpotJVMCIRuntime.runtime().getConfig(); - final long threadId = Thread.currentThread().getId(); - long startCompilationTime = System.nanoTime(); - HotSpotInstalledCode installedCode = null; - final boolean isOSR = entryBCI != Compiler.INVOCATION_ENTRY_BCI; - - // Log a compilation event. - CompilationEvent compilationEvent = eventProvider.newCompilationEvent(); - - // If there is already compiled code for this method on our level we simply return. - // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we - // only need to check for that value. - if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) { - return; - } - - CompilationResult result = null; - try (DebugCloseable a = CompilationTime.start()) { - CompilationStatistics stats = CompilationStatistics.create(method, isOSR); - final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); - final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); - if (printCompilation) { - TTY.println(getMethodDescription() + "..."); - } - - TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); - final long start; - final long allocatedBytesBefore; - if (printAfterCompilation || printCompilation) { - start = System.currentTimeMillis(); - allocatedBytesBefore = printAfterCompilation || printCompilation ? Lazy.threadMXBean.getThreadAllocatedBytes(threadId) : 0L; - } else { - start = 0L; - allocatedBytesBefore = 0L; - } - - try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { - // Begin the compilation event. - compilationEvent.begin(); - - result = compiler.compile(method, entryBCI, mustRecordMethodInlining(config)); - - result.setId(getId()); - } catch (Throwable e) { - throw Debug.handle(e); - } finally { - // End the compilation event. - compilationEvent.end(); - - filter.remove(); - - if (printAfterCompilation || printCompilation) { - final long stop = System.currentTimeMillis(); - final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1; - final long allocatedBytesAfter = Lazy.threadMXBean.getThreadAllocatedBytes(threadId); - final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024; - - if (printAfterCompilation) { - TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes)); - } else if (printCompilation) { - TTY.println(String.format("%-6d JVMCI %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes)); - } - } - } - - try (DebugCloseable b = CodeInstallationTime.start()) { - installedCode = (HotSpotInstalledCode) installMethod(result); - } - stats.finish(method, installedCode); - } catch (BailoutException bailout) { - BAILOUTS.increment(); - if (ExitVMOnBailout.getValue()) { - TTY.out.println(method.format("Bailout in %H.%n(%p)")); - bailout.printStackTrace(TTY.out); - System.exit(-1); - } else if (PrintBailout.getValue()) { - TTY.out.println(method.format("Bailout in %H.%n(%p)")); - bailout.printStackTrace(TTY.out); - } - } catch (Throwable t) { - if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) { - t.printStackTrace(TTY.out); - } - - // Log a failure event. - CompilerFailureEvent event = eventProvider.newCompilerFailureEvent(); - if (event.shouldWrite()) { - event.setCompileId(getId()); - event.setMessage(t.getMessage()); - event.commit(); - } - - if (ExitVMOnException.getValue()) { - System.exit(-1); - } - } finally { - int compiledBytecodes = 0; - int codeSize = 0; - if (result != null) { - compiledBytecodes = result.getBytecodeSize(); - } - if (installedCode != null) { - codeSize = installedCode.getSize(); - } - CompiledBytecodes.add(compiledBytecodes); - - // Log a compilation event. - if (compilationEvent.shouldWrite()) { - compilationEvent.setMethod(method.format("%H.%n(%p)")); - compilationEvent.setCompileId(getId()); - compilationEvent.setCompileLevel(config.compilationLevelFullOptimization); - compilationEvent.setSucceeded(result != null && installedCode != null); - compilationEvent.setIsOsr(isOSR); - compilationEvent.setCodeSize(codeSize); - compilationEvent.setInlinedBytes(compiledBytecodes); - compilationEvent.commit(); - } - - if (jvmciEnv != 0) { - long ctask = unsafe.getAddress(jvmciEnv + config.jvmciEnvTaskOffset); - assert ctask != 0L; - unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, compiledBytecodes); - } - long compilationTime = System.nanoTime() - startCompilationTime; - if ((config.ciTime || config.ciTimeEach) && installedCode != null) { - long timeUnitsPerSecond = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS); - CompilerToVM c2vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM(); - c2vm.notifyCompilationStatistics(id, method, entryBCI != Compiler.INVOCATION_ENTRY_BCI, compiledBytecodes, compilationTime, timeUnitsPerSecond, installedCode); - } - } - } - - /** - * Determines whether to disable method inlining recording for the method being compiled. - */ - private boolean mustRecordMethodInlining(HotSpotVMConfig config) { - if (config.ciTime || config.ciTimeEach || CompiledBytecodes.isEnabled()) { - return true; - } - if (jvmciEnv == 0 || unsafe.getByte(jvmciEnv + config.jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0) { - return true; - } - return false; - } - - private String getMethodDescription() { - return String.format("%-6d JVMCI %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(), - entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); - } - - private InstalledCode installMethod(final CompilationResult compResult) { - final HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getCodeCache(); - InstalledCode installedCode = null; - try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { - installedCode = codeCache.installMethod(method, compResult, jvmciEnv, installAsDefault); - } catch (Throwable e) { - throw Debug.handle(e); - } - return installedCode; - } - - @Override - public String toString() { - return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; - } - - /** - * Compiles a method to machine code. - */ - public static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) { - // Ensure a debug configuration for this thread is initialized - if (Debug.isEnabled() && DebugScope.getConfig() == null) { - DebugEnvironment.initialize(TTY.out); - } - - CompilationTask task = new CompilationTask(method, entryBCI, jvmciEnv, id, true); - try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) { - task.runCompilation(); - } - return; - } -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompileTheWorld.java Thu Jul 23 22:16:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.hotspot; - -import static jdk.internal.jvmci.compiler.Compiler.*; -import static jdk.internal.jvmci.debug.internal.MemUseTrackerImpl.*; - -import java.io.*; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.jar.*; -import java.util.stream.*; - -import jdk.internal.jvmci.compiler.*; -import jdk.internal.jvmci.compiler.CompilerThreadFactory.DebugConfigAccess; -import jdk.internal.jvmci.compiler.Compiler; -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.debug.internal.*; -import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.options.*; -import jdk.internal.jvmci.options.OptionUtils.OptionConsumer; -import jdk.internal.jvmci.options.OptionValue.OverrideScope; -import jdk.internal.jvmci.runtime.*; - -/** - * This class implements compile-the-world functionality with JVMCI. - */ -public final class CompileTheWorld { - - /** - * Magic token to trigger reading files from the boot class path. - */ - public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; - - public static class Options { - // @formatter:off - @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) - public static final OptionValue<String> CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH); - @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) - public static final OptionValue<Boolean> CompileTheWorldVerbose = new OptionValue<>(true); - @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) - public static final OptionValue<Integer> CompileTheWorldIterations = new OptionValue<>(1); - @Option(help = "Only compile methods matching this filter", type = OptionType.Debug) - public static final OptionValue<String> CompileTheWorldMethodFilter = new OptionValue<>(null); - @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug) - public static final OptionValue<String> CompileTheWorldExcludeMethodFilter = new OptionValue<>(null); - @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionValue<Integer> CompileTheWorldStartAt = new OptionValue<>(1); - @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionValue<Integer> CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); - @Option(help = "Option value overrides to use during compile the world. For example, " + - "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " + - "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug) - public static final OptionValue<String> CompileTheWorldConfig = new OptionValue<>(null); - - @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug) - public static final OptionValue<Boolean> CompileTheWorldMultiThreaded = new OptionValue<>(false); - @Option(help = "Number of threads to use for multithreaded CTW. Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug) - public static final OptionValue<Integer> CompileTheWorldThreads = new OptionValue<>(0); - // @formatter:on - - /** - * Overrides {@link #CompileTheWorldStartAt} and {@link #CompileTheWorldStopAt} from - * {@code -XX} HotSpot options of the same name if the latter have non-default values. - */ - public static void overrideWithNativeOptions(HotSpotVMConfig c) { - if (c.compileTheWorldStartAt != 1) { - CompileTheWorldStartAt.setValue(c.compileTheWorldStartAt); - } - if (c.compileTheWorldStopAt != Integer.MAX_VALUE) { - CompileTheWorldStopAt.setValue(c.compileTheWorldStopAt); - } - } - } - - /** - * A mechanism for overriding JVMCI options that affect compilation. A {@link Config} object - * should be used in a try-with-resources statement to ensure overriding of options is scoped - * properly. For example: - * - * <pre> - * Config config = ...; - * try (AutoCloseable s = config == null ? null : config.apply()) { - * // perform a JVMCI compilation - * } - * </pre> - */ - @SuppressWarnings("serial") - public static class Config extends HashMap<OptionValue<?>, Object> implements OptionConsumer { - /** - * Creates a {@link Config} object by parsing a set of space separated override options. - * - * @param options a space separated set of option value settings with each option setting in - * a format compatible with - * {@link OptionUtils#parseOption(String, OptionConsumer)}. Ignored if null. - */ - public Config(String options) { - if (options != null) { - for (String option : options.split("\\s+")) { - OptionUtils.parseOption(option, this); - } - } - } - - /** - * Applies the overrides represented by this object. The overrides are in effect until - * {@link OverrideScope#close()} is called on the returned object. - */ - OverrideScope apply() { - return OptionValue.override(this); - } - - public void set(OptionDescriptor desc, Object value) { - put(desc.getOptionValue(), value); - } - } - - /** List of Zip/Jar files to compile (see {@link Options#CompileTheWorldClasspath}). */ - private final String files; - - /** Class index to start compilation at (see {@link Options#CompileTheWorldStartAt}). */ - private final int startAt; - - /** Class index to stop compilation at (see {@link Options#CompileTheWorldStopAt}). */ - private final int stopAt; - - /** Only compile methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] methodFilters; - - /** Exclude methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] excludeMethodFilters; - - // Counters - private int classFileCounter = 0; - private AtomicLong compiledMethodsCounter = new AtomicLong(); - private AtomicLong compileTime = new AtomicLong(); - private AtomicLong memoryUsed = new AtomicLong(); - - private boolean verbose; - private final Config config; - - /** - * Signal that the threads should start compiling in multithreaded mode. - */ - private boolean running; - - private ThreadPoolExecutor threadPool; - - /** - * Creates a compile-the-world instance. - * - * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile - * @param startAt index of the class file to start compilation at - * @param stopAt index of the class file to stop compilation at - * @param methodFilters - * @param excludeMethodFilters - */ - public CompileTheWorld(String files, Config config, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, boolean verbose) { - this.files = files; - this.startAt = startAt; - this.stopAt = stopAt; - this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); - this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); - this.verbose = verbose; - this.config = config; - - // We don't want the VM to exit when a method fails to compile... - config.putIfAbsent(ExitVMOnException, false); - - // ...but we want to see exceptions. - config.putIfAbsent(PrintBailout, true); - config.putIfAbsent(PrintStackTraceOnException, true); - config.putIfAbsent(HotSpotResolvedJavaMethodImpl.Options.UseProfilingInformation, false); - } - - /** - * Compiles all methods in all classes in the Zip/Jar archive files in - * {@link Options#CompileTheWorldClasspath}. If {@link Options#CompileTheWorldClasspath} - * contains the magic token {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the - * files from the boot class path. - */ - public void compile() throws Throwable { - // By default only report statistics for the CTW threads themselves - if (JVMCIDebugConfig.DebugValueThreadFilter.hasDefaultValue()) { - JVMCIDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld"); - } - - if (SUN_BOOT_CLASS_PATH.equals(files)) { - final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); - String bcpFiles = ""; - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - // We stop at rt.jar, unless it is the first boot class path entry. - if (entry.endsWith("rt.jar") && (i > 0)) { - break; - } - if (i > 0) { - bcpFiles += File.pathSeparator; - } - bcpFiles += entry; - } - compile(bcpFiles); - } else { - compile(files); - } - } - - public void println() { - println(""); - } - - public void println(String format, Object... args) { - println(String.format(format, args)); - } - - public void println(String s) { - if (verbose) { - TTY.println(s); - } - } - - @SuppressWarnings("unused") - private static void dummy() { - } - - /** - * Compiles all methods in all classes in the Zip/Jar files passed. - * - * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile - * @throws IOException - */ - private void compile(String fileList) throws IOException { - final String[] entries = fileList.split(File.pathSeparator); - long start = System.currentTimeMillis(); - - CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { - public JVMCIDebugConfig getDebugConfig() { - if (Debug.isEnabled() && DebugScope.getConfig() == null) { - return DebugEnvironment.initialize(System.out); - } - return null; - } - }); - - try { - // compile dummy method to get compiler initilized outside of the config debug override. - HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( - CompileTheWorld.class.getDeclaredMethod("dummy")); - CompilationTask task = new CompilationTask(dummyMethod, Compiler.INVOCATION_ENTRY_BCI, 0L, dummyMethod.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false); - task.runCompilation(); - } catch (NoSuchMethodException | SecurityException e1) { - e1.printStackTrace(); - } - - /* - * Always use a thread pool, even for single threaded mode since it simplifies the use of - * DebugValueThreadFilter to filter on the thread names. - */ - int threadCount = 1; - if (Options.CompileTheWorldMultiThreaded.getValue()) { - threadCount = Options.CompileTheWorldThreads.getValue(); - if (threadCount == 0) { - threadCount = Runtime.getRuntime().availableProcessors(); - } - } else { - running = true; - } - threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory); - - try (OverrideScope s = config.apply()) { - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - // For now we only compile all methods in all classes in zip/jar files. - if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { - println("CompileTheWorld : Skipped classes in " + entry); - println(); - continue; - } - - if (methodFilters == null || methodFilters.length == 0) { - println("CompileTheWorld : Compiling all classes in " + entry); - } else { - String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); - } - if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { - String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); - } - println(); - - URL url = new URL("jar", "", "file:" + entry + "!/"); - ClassLoader loader = new URLClassLoader(new URL[]{url}); - - JarFile jarFile = new JarFile(entry); - Enumeration<JarEntry> e = jarFile.entries(); - - while (e.hasMoreElements()) { - JarEntry je = e.nextElement(); - if (je.isDirectory() || !je.getName().endsWith(".class")) { - continue; - } - - // Are we done? - if (classFileCounter >= stopAt) { - break; - } - - String className = je.getName().substring(0, je.getName().length() - ".class".length()); - String dottedClassName = className.replace('/', '.'); - classFileCounter++; - - if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) { - continue; - } - if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) { - continue; - } - - if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) { - continue; - } - - try { - // Load and initialize class - Class<?> javaClass = Class.forName(dottedClassName, true, loader); - - // Pre-load all classes in the constant pool. - try { - HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass); - ConstantPool constantPool = objectType.constantPool(); - for (int cpi = 1; cpi < constantPool.length(); cpi++) { - constantPool.loadReferencedType(cpi, HotSpotConstantPool.Bytecodes.LDC); - } - } catch (Throwable t) { - // If something went wrong during pre-loading we just ignore it. - println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); - } - - // Are we compiling this class? - MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); - if (classFileCounter >= startAt) { - println("CompileTheWorld (%d) : %s", classFileCounter, className); - - // Compile each constructor/method in the class. - for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); - if (canBeCompiled(javaMethod, constructor.getModifiers())) { - compileMethod(javaMethod); - } - } - for (Method method : javaClass.getDeclaredMethods()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); - if (canBeCompiled(javaMethod, method.getModifiers())) { - compileMethod(javaMethod); - } - } - } - } catch (Throwable t) { - println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); - t.printStackTrace(); - } - } - jarFile.close(); - } - } - - if (!running) { - startThreads(); - } - int wakeups = 0; - while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { - if (wakeups % 15 == 0) { - TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); - } - try { - threadPool.awaitTermination(1, TimeUnit.SECONDS); - wakeups++; - } catch (InterruptedException e) { - } - } - threadPool = null; - - long elapsedTime = System.currentTimeMillis() - start; - - println(); - if (Options.CompileTheWorldMultiThreaded.getValue()) { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, - compileTime.get(), memoryUsed.get()); - } else { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); - } - } - - private synchronized void startThreads() { - running = true; - // Wake up any waiting threads - notifyAll(); - } - - private synchronized void waitToRun() { - while (!running) { - try { - wait(); - } catch (InterruptedException e) { - } - } - } - - private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { - if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { - return; - } - if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { - return; - } - Future<?> task = threadPool.submit(new Runnable() { - public void run() { - waitToRun(); - try (OverrideScope s = config.apply()) { - compileMethod(method, classFileCounter); - } - } - }); - if (threadPool.getCorePoolSize() == 1) { - task.get(); - } - } - - /** - * Compiles a method and gathers some statistics. - */ - private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { - try { - long start = System.currentTimeMillis(); - long allocatedAtStart = getCurrentThreadAllocatedBytes(); - - CompilationTask task = new CompilationTask(method, Compiler.INVOCATION_ENTRY_BCI, 0L, method.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false); - task.runCompilation(); - - memoryUsed.getAndAdd(getCurrentThreadAllocatedBytes() - allocatedAtStart); - compileTime.getAndAdd(System.currentTimeMillis() - start); - compiledMethodsCounter.incrementAndGet(); - } catch (Throwable t) { - // Catch everything and print a message - println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); - t.printStackTrace(TTY.out); - } - } - - /** - * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). - * - * @return true if it can be compiled, false otherwise - */ - private static boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return false; - } - HotSpotVMConfig c = HotSpotJVMCIRuntime.runtime().getConfig(); - if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { - return false; - } - // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods - if (!javaMethod.canBeInlined()) { - return false; - } - // Skip @Snippets for now - for (Annotation annotation : javaMethod.getAnnotations()) { - if (annotation.annotationType().getName().equals("com.oracle.graal.replacements.Snippet")) { - return false; - } - } - return true; - } - -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java Fri Jul 24 02:11:18 2015 +0200 @@ -30,7 +30,6 @@ import jdk.internal.jvmci.code.CompilationResult.*; import jdk.internal.jvmci.code.DataSection.*; import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.debug.*; import jdk.internal.jvmci.meta.*; /** @@ -100,12 +99,7 @@ } public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) { - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); - } - if (Debug.isLogEnabled()) { - Debug.log("%s", disassemble(installedCode)); - } + HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult); return installedCode; }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java Fri Jul 24 02:11:18 2015 +0200 @@ -323,4 +323,17 @@ vmEventListener.notifyShutdown(); } } + + /** + * Shuts down the runtime. + * + * Called from the VM. + * + * @param hotSpotCodeCacheProvider + */ + void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) { + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { + vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compResult); + } + } }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIVMEventListener.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIVMEventListener.java Fri Jul 24 02:11:18 2015 +0200 @@ -22,36 +22,9 @@ */ package jdk.internal.jvmci.hotspot; -import static jdk.internal.jvmci.hotspot.CompileTheWorld.Options.*; -import jdk.internal.jvmci.debug.*; -import jdk.internal.jvmci.hotspot.CompileTheWorld.*; import jdk.internal.jvmci.service.*; @ServiceProvider(HotSpotVMEventListener.class) public class HotSpotJVMCIVMEventListener implements HotSpotVMEventListener { - @Override - public void notifyCompileTheWorld() throws Throwable { - CompilerToVM compilerToVM = HotSpotJVMCIRuntime.runtime().getCompilerToVM(); - int iterations = CompileTheWorld.Options.CompileTheWorldIterations.getValue(); - for (int i = 0; i < iterations; i++) { - compilerToVM.resetCompilationStatistics(); - TTY.println("CompileTheWorld : iteration " + i); - CompileTheWorld ctw = new CompileTheWorld(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(), - CompileTheWorldStopAt.getValue(), CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue()); - ctw.compile(); - } - System.exit(0); - } - - @Override - public void notifyShutdown() { - // nothing to do - } - - @Override - public void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) { - HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); - CompilationTask.compileMethod(method, entryBCI, jvmciEnv, id); - } }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethod.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethod.java Fri Jul 24 02:11:18 2015 +0200 @@ -23,14 +23,36 @@ package jdk.internal.jvmci.hotspot; import static java.util.FormattableFlags.*; -import static jdk.internal.jvmci.debug.Debug.*; - import java.util.*; -import jdk.internal.jvmci.debug.*; import jdk.internal.jvmci.meta.*; -public abstract class HotSpotMethod implements JavaMethod, Formattable, JavaMethodContex { +public abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{ + + public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { + if (flags == 0 && width < 0) { + return s; + } + StringBuilder sb = new StringBuilder(s); + + // apply width and justification + int len = sb.length(); + if (len < width) { + for (int i = 0; i < width - len; i++) { + if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) { + sb.append(' '); + } else { + sb.insert(0, ' '); + } + } + } + + String res = sb.toString(); + if ((flags & UPPERCASE) == UPPERCASE) { + res = res.toUpperCase(); + } + return res; + } protected String name;
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotProfilingInfo.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotProfilingInfo.java Fri Jul 24 02:11:18 2015 +0200 @@ -22,12 +22,12 @@ */ package jdk.internal.jvmci.hotspot; -import jdk.internal.jvmci.debug.*; import jdk.internal.jvmci.meta.*; public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified { - private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData"); + // private static final DebugMetric metricInsufficentSpace = + // Debug.metric("InsufficientSpaceForProfilingData"); private final HotSpotMethodData methodData; private final HotSpotResolvedJavaMethod method; @@ -158,7 +158,7 @@ if (!methodData.isWithin(currentPosition)) { exceptionPossiblyNotRecorded = true; - metricInsufficentSpace.increment(); + // metricInsufficentSpace.increment(); } }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Fri Jul 24 02:11:18 2015 +0200 @@ -40,7 +40,7 @@ */ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MethodIdHolder { - static class Options { + public static class Options { // @formatter:off @Option(help = "", type = OptionType.Debug) public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java Fri Jul 24 02:11:18 2015 +0200 @@ -22,6 +22,8 @@ */ package jdk.internal.jvmci.hotspot; +import jdk.internal.jvmci.code.*; + public interface HotSpotVMEventListener { /** @@ -48,4 +50,14 @@ */ default void notifyShutdown() { } + + /** + * Notify on successful install into the CodeCache. + * + * @param hotSpotCodeCacheProvider + * @param installedCode + * @param compResult + */ + default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) { + } }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/InitTimer.java Thu Jul 23 22:16:06 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/InitTimer.java Fri Jul 24 02:11:18 2015 +0200 @@ -22,12 +22,9 @@ */ package jdk.internal.jvmci.hotspot; -import jdk.internal.jvmci.debug.*; - /** - * A facility for timing a step in the runtime initialization sequence. This exists separate from - * {@link DebugTimer} as it must be independent from all other JVMCI code so as to not perturb the - * initialization sequence. + * A facility for timing a step in the runtime initialization sequence. This must be independent + * from all other JVMCI code so as to not perturb the initialization sequence. */ public final class InitTimer implements AutoCloseable { final String name;
--- a/make/bsd/makefiles/compiler1.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/bsd/makefiles/compiler1.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = client-nojvmci endif \ No newline at end of file
--- a/make/bsd/makefiles/compiler2.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/bsd/makefiles/compiler2.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif \ No newline at end of file
--- a/make/bsd/makefiles/tiered.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/bsd/makefiles/tiered.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif
--- a/make/defs.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/defs.make Fri Jul 24 02:11:18 2015 +0200 @@ -381,9 +381,6 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotResolvedJavaFieldImpl EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotResolvedJavaMethodImpl -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.CompileTheWorld -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.compiler.Compiler -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.debug.JVMCIDebugConfig # The use of CONDITIONAL_EXPORT_LIST is for the checking # done by verify_defs_make in jvmci.make
--- a/make/excludeSrc.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/excludeSrc.make Fri Jul 24 02:11:18 2015 +0200 @@ -127,6 +127,11 @@ memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp endif +ifeq ($(INCLUDE_JVMCI), false) + CXXFLAGS += -DINCLUDE_JVMCI=0 + CFLAGS += -DINCLUDE_JVMCI=0 +endif + -include $(HS_ALT_MAKE)/excludeSrc.make .PHONY: $(HS_ALT_MAKE)/excludeSrc.make
--- a/make/linux/makefiles/compiler1.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/linux/makefiles/compiler1.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = client-nojvmci endif \ No newline at end of file
--- a/make/linux/makefiles/compiler2.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/linux/makefiles/compiler2.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif \ No newline at end of file
--- a/make/linux/makefiles/tiered.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/linux/makefiles/tiered.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif \ No newline at end of file
--- a/make/solaris/makefiles/compiler1.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/compiler1.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = client-nojvmci endif
--- a/make/solaris/makefiles/compiler2.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/compiler2.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif
--- a/make/solaris/makefiles/debug.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/debug.make Fri Jul 24 02:11:18 2015 +0200 @@ -46,9 +46,6 @@ # Linker mapfiles MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \ $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug -#ifdef JVMCI -MAPFILE += $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-JVMCI -#endif # This mapfile is only needed when compiling with dtrace support, # and mustn't be otherwise.
--- a/make/solaris/makefiles/fastdebug.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/fastdebug.make Fri Jul 24 02:11:18 2015 +0200 @@ -117,9 +117,6 @@ # Linker mapfiles MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \ $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug -#ifdef JVMCI -MAPFILE += $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-JVMCI -#endif # This mapfile is only needed when compiling with dtrace support, # and mustn't be otherwise.
--- a/make/solaris/makefiles/optimized.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/optimized.make Fri Jul 24 02:11:18 2015 +0200 @@ -54,9 +54,6 @@ # Linker mapfiles MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers -#ifdef JVMCI -MAPFILE += $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-JVMCI -#endif # This mapfile is only needed when compiling with dtrace support, # and mustn't be otherwise.
--- a/make/solaris/makefiles/product.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/product.make Fri Jul 24 02:11:18 2015 +0200 @@ -66,9 +66,6 @@ # Linker mapfiles MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers -ifdef JVMCI -MAPFILE += $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-JVMCI -endif ifndef USE_GCC # This mapfile is only needed when compiling with dtrace support,
--- a/make/solaris/makefiles/tiered.make Thu Jul 23 22:16:06 2015 +0200 +++ b/make/solaris/makefiles/tiered.make Fri Jul 24 02:11:18 2015 +0200 @@ -30,8 +30,6 @@ CFLAGS += -DCOMPILER2 -DCOMPILER1 -ifeq ($(INCLUDE_JVMCI), true) - CFLAGS += -DJVMCI -else +ifeq ($(INCLUDE_JVMCI), false) VM_SUBDIR = server-nojvmci endif
--- a/mx.jvmci/suite.py Thu Jul 23 22:16:06 2015 +0200 +++ b/mx.jvmci/suite.py Fri Jul 24 02:11:18 2015 +0200 @@ -15,9 +15,9 @@ }, "C1VISUALIZER_DIST" : { - "path" : "lib/c1visualizer_2014-04-22.zip", - "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2014-04-22.zip"], - "sha1" : "220488d87affb569b893c7201f8ce5d2b0e03141", + "path" : "lib/c1visualizer_2015-07-22.zip", + "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2015-07-22.zip"], + "sha1" : "7ead6b2f7ed4643ef4d3343a5562e3d3f39564ac", }, "JOL_INTERNALS" : { @@ -110,17 +110,29 @@ "sourceDirs" : ["src"], "checkstyle" : "com.oracle.graal.graph", "dependencies" : [ + "jdk.internal.jvmci.service", + ], + "annotationProcessors" : ["jdk.internal.jvmci.options.processor"], + "javaCompliance" : "1.8", + "workingSets" : "JVMCI,Debug", + }, + + "com.oracle.graal.debug" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "checkstyle" : "com.oracle.graal.graph", + "dependencies" : [ + "jdk.internal.jvmci.debug", "jdk.internal.jvmci.options", "jdk.internal.jvmci.code", - "jdk.internal.jvmci.service", ], "annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"], "javaCompliance" : "1.8", "workingSets" : "JVMCI,Debug", }, - "jdk.internal.jvmci.debug.test" : { - "subDir" : "jvmci", + "com.oracle.graal.debug.test" : { + "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ "mx:JUNIT", @@ -143,7 +155,8 @@ "subDir" : "jvmci", "sourceDirs" : ["src"], "dependencies" : [ - "jdk.internal.jvmci.debug", + "jdk.internal.jvmci.options", + "jdk.internal.jvmci.code", ], "checkstyle" : "com.oracle.graal.graph", "annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"], @@ -201,7 +214,9 @@ "jdk.internal.jvmci.hotspotvmconfig", "jdk.internal.jvmci.runtime", "jdk.internal.jvmci.common", - "jdk.internal.jvmci.compiler", + "jdk.internal.jvmci.options", + "jdk.internal.jvmci.runtime", + "jdk.internal.jvmci.debug", ], "annotationProcessors" : [ "JVMCI_HOTSPOTVMCONFIG_PROCESSOR",
--- a/src/cpu/sparc/vm/compiledIC_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/sparc/vm/compiledIC_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -102,7 +102,7 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) { address stub = find_stub(); -#ifdef JVMCI +#if INCLUDE_JVMCI if (stub == NULL) { set_destination_mt_safe(entry); return; @@ -159,7 +159,7 @@ // Verify stub. address stub = find_stub(); -#ifndef JVMCI +#if !INCLUDE_JVMCI assert(stub != NULL, "no stub found for static call"); // Creation also verifies the object. NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1644,7 +1644,7 @@ bind(skip_receiver_profile); // The method data pointer needs to be updated to reflect the new target. -#ifdef JVMCI +#if INCLUDE_JVMCI if (MethodProfileWidth == 0) { update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); } @@ -1655,7 +1655,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI void InterpreterMacroAssembler::profile_called_method(Register method, Register scratch) { assert_different_registers(method, scratch); if (ProfileInterpreter && MethodProfileWidth > 0) { @@ -1681,7 +1681,7 @@ if (is_virtual_call) { increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); } -#ifdef JVMCI +#if INCLUDE_JVMCI else { increment_mdp_data_at(in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()), scratch); } @@ -1691,11 +1691,11 @@ int non_profiled_offset = -1; if (use_non_profiled_counter) { non_profiled_offset = in_bytes(CounterData::count_offset()); - #ifdef JVMCI +#if INCLUDE_JVMCI if (!is_virtual_call) { non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()); } - #endif +#endif assert(non_profiled_offset >= 0, "must be"); }
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -43,7 +43,7 @@ #include "compiler/compileBroker.hpp" #include "shark/sharkCompiler.hpp" #endif -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciJavaAccess.hpp" #endif @@ -995,7 +995,7 @@ // Jump to the compiled code just as if compiled code was doing it. __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3); -#ifdef JVMCI +#if INCLUDE_JVMCI // check if this call should be routed towards a specific entry point __ ld(Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), G1); __ cmp(G0, G1); @@ -3473,7 +3473,7 @@ pad += StackShadowPages*16 + 32; } #endif -#ifdef JVMCI +#if INCLUDE_JVMCI pad += 1000; // Increase the buffer size when compiling for JVMCI #endif #ifdef _LP64 @@ -3543,7 +3543,7 @@ __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode); -#ifdef JVMCI +#if INCLUDE_JVMCI masm->block_comment("BEGIN JVMCI"); int implicit_exception_uncommon_trap_offset = __ offset() - start; __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()), O7); @@ -3576,7 +3576,7 @@ __ ba(after_fetch_unroll_info_call); __ delayed()->nop(); // Delay slot masm->block_comment("END JVMCI"); -#endif // JVMCI +#endif // INCLUDE_JVMCI int exception_offset = __ offset() - start; @@ -3659,7 +3659,7 @@ __ reset_last_Java_frame(); -#ifdef JVMCI +#if INCLUDE_JVMCI __ bind(after_fetch_unroll_info_call); #endif // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers @@ -3727,7 +3727,7 @@ masm->flush(); _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_words); _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); -#ifdef JVMCI +#if INCLUDE_JVMCI _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset); _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset); #endif
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -203,7 +203,7 @@ address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache -#ifdef JVMCI +#if INCLUDE_JVMCI // Check if we need to take lock at entry of synchronized method. { Label L;
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -2949,7 +2949,7 @@ // get target Method* & entry point __ lookup_virtual_method(Rrecv, Rindex, G5_method); __ profile_arguments_type(G5_method, Rcall, Gargs, true); -#ifdef JVMCI +#if INCLUDE_JVMCI __ profile_called_method(G5_method, Rtemp); #endif __ call_from_interpreter(Rcall, Gargs, Rret); @@ -3206,7 +3206,7 @@ assert_different_registers(Rcall, G5_method, Gargs, Rret); __ profile_arguments_type(G5_method, Rcall, Gargs, true); -#ifdef JVMCI +#if INCLUDE_JVMCI __ profile_called_method(G5_method, Rscratch); #endif __ call_from_interpreter(Rcall, Gargs, Rret);
--- a/src/cpu/x86/vm/c2_globals_x86.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/c2_globals_x86.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -86,7 +86,7 @@ define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoBundling, false); -#ifdef JVMCI +#if INCLUDE_JVMCI define_pd_global(intx, ReservedCodeCacheSize, 64*M); #else define_pd_global(intx, ReservedCodeCacheSize, 48*M);
--- a/src/cpu/x86/vm/frame_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/frame_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -460,11 +460,11 @@ // This is the sp before any possible extension (adapter/locals). intptr_t* unextended_sp = interpreter_frame_sender_sp(); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } -#endif // COMPILER2 || JVMCI +#endif // COMPILER2 || INCLUDE_JVMCI return frame(sender_sp, unextended_sp, link(), sender_pc()); }
--- a/src/cpu/x86/vm/globals_x86.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/globals_x86.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -47,7 +47,7 @@ // the the vep is aligned at CodeEntryAlignment whereas c2 only aligns // the uep and the vep doesn't get real alignment but just slops on by // only assured that the entry instruction meets the 5 byte size requirement. -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI define_pd_global(intx, CodeEntryAlignment, 32); #else define_pd_global(intx, CodeEntryAlignment, 16);
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1129,7 +1129,7 @@ bind(skip_receiver_profile); // The method data pointer needs to be updated to reflect the new target. -#ifdef JVMCI +#if INCLUDE_JVMCI if (MethodProfileWidth == 0) { update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size())); } @@ -1140,7 +1140,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI void InterpreterMacroAssembler::profile_called_method(Register method, Register mdp, Register reg2) { assert_different_registers(method, mdp, reg2); if (ProfileInterpreter && MethodProfileWidth > 0) { @@ -1178,7 +1178,7 @@ if (is_virtual_call) { increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); } -#ifdef JVMCI +#if INCLUDE_JVMCI else { increment_mdp_data_at(mdp, in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset())); } @@ -1188,11 +1188,11 @@ int non_profiled_offset = -1; if (use_non_profiled_counter) { non_profiled_offset = in_bytes(CounterData::count_offset()); - #ifdef JVMCI +#if INCLUDE_JVMCI if (!is_virtual_call) { non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()); } - #endif +#endif assert(non_profiled_offset >= 0, "must be"); }
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -2945,7 +2945,7 @@ } // !defined(COMPILER2) is because of stupid core builds -#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) || defined(JVMCI) +#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) || INCLUDE_JVMCI void MacroAssembler::empty_FPU_stack() { if (VM_Version::supports_mmx()) { emms(); @@ -2953,7 +2953,7 @@ for (int i = 8; i-- > 0; ) ffree(i); } } -#endif // !LP64 || C1 || !C2 +#endif // !LP64 || C1 || !C2 || JVMCI // Defines obj, preserves var_size_in_bytes
--- a/src/cpu/x86/vm/relocInfo_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/relocInfo_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -181,7 +181,7 @@ #ifdef _LP64 typedef Assembler::WhichOperand WhichOperand; WhichOperand which = (WhichOperand) format(); -#ifndef JVMCI +#if !INCLUDE_JVMCI assert((which == Assembler::disp32_operand) == !Assembler::is_polling_page_far(), "format not set correctly"); #endif if (which == Assembler::disp32_operand) {
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -40,7 +40,7 @@ #ifdef COMPILER2 #include "opto/runtime.hpp" #endif -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciJavaAccess.hpp" #endif @@ -141,7 +141,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { int vect_words = 0; int ymmhi_offset = -1; -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (save_vectors) { assert(UseAVX > 0, "256bit vectors are supported only with AVX"); assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); @@ -244,7 +244,7 @@ map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg()); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (save_vectors) { assert(ymmhi_offset != -1, "save area must exist"); map->set_callee_saved(YMMHI_STACK_OFFSET( 0), xmm0->as_VMReg()->next()->next()->next()->next()); @@ -309,7 +309,7 @@ // Pop arg register save area __ addptr(rsp, frame::arg_reg_save_area_bytes); } -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (restore_vectors) { // Restore upper half of YMM registes. assert(UseAVX > 0, "256bit vectors are supported only with AVX"); @@ -731,7 +731,7 @@ __ block_comment("} verify_i2ce "); } -#ifdef JVMCI +#if INCLUDE_JVMCI if (frame_extension_argument != -1) { // The frame_extension_argument is an int that describes the // expected amount of argument space in the caller frame. If that @@ -802,7 +802,7 @@ // Pre-load the register-jump target early, to schedule it better. __ movptr(r11, Address(rbx, in_bytes(Method::from_compiled_offset()))); -#ifdef JVMCI +#if INCLUDE_JVMCI // check if this call should be routed towards a specific entry point __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0); Label no_alternative_target; @@ -3430,7 +3430,7 @@ __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved __ jmp(cont); -#ifdef JVMCI +#if INCLUDE_JVMCI int implicit_exception_uncommon_trap_offset = __ pc() - start; __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()))); @@ -3454,7 +3454,7 @@ Label after_fetch_unroll_info_call; __ jmp(after_fetch_unroll_info_call); -#endif // JVMCI +#endif // INCLUDE_JVMCI int exception_offset = __ pc() - start; @@ -3541,7 +3541,7 @@ __ reset_last_Java_frame(false, false); -#ifdef JVMCI +#if INCLUDE_JVMCI __ bind(after_fetch_unroll_info_call); #endif @@ -3719,7 +3719,7 @@ _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); -#ifdef JVMCI +#if INCLUDE_JVMCI _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset); _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset); #endif
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -204,7 +204,7 @@ __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); -#ifdef JVMCI +#if INCLUDE_JVMCI // Check if we need to take lock at entry of synchronized method. { Label L;
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -3039,7 +3039,7 @@ // get target Method* & entry point __ lookup_virtual_method(rax, index, method); -#ifdef JVMCI +#if INCLUDE_JVMCI // r14: MethodDataPointer (r14 is callee saved) __ profile_called_method(method, r14, r13); #endif @@ -3143,7 +3143,7 @@ __ testptr(rbx, rbx); __ jcc(Assembler::zero, no_such_method); -#ifdef JVMCI +#if INCLUDE_JVMCI // r13: MethodDataPointer (r13 is callee saved) __ profile_called_method(rbx, r13, r14); #endif
--- a/src/cpu/x86/vm/vm_version_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -668,7 +668,7 @@ } } #endif -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (MaxVectorSize > 0) { if (!is_power_of_2(MaxVectorSize)) { warning("MaxVectorSize must be a power of 2");
--- a/src/os/windows/vm/os_windows.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/os/windows/vm/os_windows.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -2253,7 +2253,7 @@ #elif _M_AMD64 PCONTEXT ctx = exceptionInfo->ContextRecord; address pc = (address)ctx->Rip; -#ifdef JVMCI +#if INCLUDE_JVMCI assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode"); if (pc[0] == 0xF7) { // set correct result values and continue after idiv instruction
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -66,7 +66,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // C2 and JVMCI use ebp as a general register see if NULL fp helps frame ret_frame2(ret_sp, NULL, addr.pc()); if (!ret_frame2.safe_for_sender(jt)) { @@ -77,7 +77,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || JVMCI*/ +#endif /* COMPILER2 || INCLUDE_JVMCI */ } *fr_addr = ret_frame; return true;
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -67,7 +67,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // C2 and JVMCI use ebp as a general register see if NULL fp helps frame ret_frame2(ret_sp, NULL, addr.pc()); if (!ret_frame2.safe_for_sender(jt)) { @@ -78,7 +78,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || JVMCI */ +#endif /* COMPILER2 || INCLUDE_JVMCI */ } *fr_addr = ret_frame; return true;
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -484,14 +484,14 @@ } #endif // COMPILER2 -#ifdef JVMCI +#if INCLUDE_JVMCI else if (sig == SIGILL && info->si_trapno == 0x100 + ST_RESERVED_FOR_USER_0) { - printf("SIGILL 0x%x 0x%x\n", info->si_trapno, ST_RESERVED_FOR_USER_0); - uc->uc_mcontext.gregs[REG_PC] = (greg_t)pc+4; - uc->uc_mcontext.gregs[REG_nPC] = (greg_t)npc + 4; - return true; + printf("SIGILL 0x%x 0x%x\n", info->si_trapno, ST_RESERVED_FOR_USER_0); + uc->uc_mcontext.gregs[REG_PC] = (greg_t)pc+4; + uc->uc_mcontext.gregs[REG_nPC] = (greg_t)npc + 4; + return true; } -#endif // JVMCI +#endif else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { // Determination of interpreter/vtable stub/compiled code null exception
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -74,7 +74,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // C2 and JVMCI use ebp as a general register see if NULL fp helps frame ret_frame2(ret_sp, NULL, addr.pc()); if (!ret_frame2.safe_for_sender(jt)) { @@ -85,7 +85,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || JVMCI */ +#endif /* COMPILER2 || INCLUDE_JVMCI */ } *fr_addr = ret_frame; return true;
--- a/src/share/vm/classfile/classFileParser.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1791,7 +1791,7 @@ if (_location != _in_method) break; // only allow for methods if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; -#ifdef JVMCI +#if INCLUDE_JVMCI case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_jvmci_hotspot_Stable_signature): if (_location != _in_field) break; // only allow for fields if (!privileged && loader_data->class_loader() != SystemDictionary::jvmci_loader()) break; // only allow in privileged code
--- a/src/share/vm/classfile/javaClasses.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -563,7 +563,7 @@ set_init_lock(mirror(), r); // Set protection domain also -#ifdef JVMCI +#if INCLUDE_JVMCI if (k->class_loader() == SystemDictionary::jvmci_loader()) { // Same protection domain as for classes loaded by the boot loader protection_domain = Handle();
--- a/src/share/vm/classfile/systemDictionary.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -64,7 +64,7 @@ #include "services/threadService.hpp" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciRuntime.hpp" #endif #if INCLUDE_TRACE @@ -96,7 +96,7 @@ bool SystemDictionary::_has_loadClassInternal = false; bool SystemDictionary::_has_checkPackageAccess = false; -#ifdef JVMCI +#if INCLUDE_JVMCI oop SystemDictionary::_jvmci_loader = NULL; oop SystemDictionary::jvmci_loader() { @@ -1865,7 +1865,7 @@ Klass** klassp = &_well_known_klasses[id]; bool must_load = (init_opt < SystemDictionary::Opt); if ((*klassp) == NULL) { -#ifdef JVMCI +#if INCLUDE_JVMCI bool is_jvmci = init_opt == SystemDictionary::Jvmci; assert(is_jvmci == (id >= (int)FIRST_JVMCI_WKID && id <= (int)LAST_JVMCI_WKID), "JVMCI WKIDs must be contiguous and separate from non-JVMCI WKIDs");
--- a/src/share/vm/classfile/systemDictionary.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -199,7 +199,6 @@ /* Support for JVMCI */ \ do_klass(BitSet_klass, java_util_BitSet, Opt ) \ /* JVMCI classes. These are loaded on-demand. */ \ - JVMCI_ONLY(do_klass(Debug_klass, jdk_internal_jvmci_debug_Debug, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotCompiledCode_klass, jdk_internal_jvmci_hotspot_HotSpotCompiledCode, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotCompiledCode_Comment_klass, jdk_internal_jvmci_hotspot_HotSpotCompiledCode_Comment, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotCompiledNmethod_klass, jdk_internal_jvmci_hotspot_HotSpotCompiledNmethod, Jvmci)) \ @@ -268,8 +267,8 @@ WKID_LIMIT, -#ifdef JVMCI - FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(Debug_klass), +#if INCLUDE_JVMCI + FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(HotSpotCompiledCode_klass), LAST_JVMCI_WKID = WK_KLASS_ENUM_NAME(AbstractValue_klass), #endif @@ -286,7 +285,7 @@ Opt, // preload tried; NULL if not present Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection Opt_Only_JDK15, // preload tried; use only with JDK1.5+ -#ifdef JVMCI +#if INCLUDE_JVMCI Jvmci, // preload tried; error if not present, use only with JVMCI #endif OPTION_LIMIT, @@ -478,7 +477,7 @@ // despite the optional loading, if you use this it must be present: return check_klass(k); } -#ifdef JVMCI +#if INCLUDE_JVMCI static Klass* check_klass_Jvmci(Klass* k) { return k; } #endif @@ -546,7 +545,7 @@ // Returns default system loader static oop java_system_loader(); -#ifdef JVMCI +#if INCLUDE_JVMCI // Returns the JVMCI loader. This will be NULL if !UseJVMCIClassLoader // in which case it's equivalent to the boot loader static oop jvmci_loader(); @@ -784,7 +783,7 @@ static Klass* _box_klasses[T_VOID+1]; static oop _java_system_loader; -#ifdef JVMCI +#if INCLUDE_JVMCI static oop _jvmci_loader; #endif
--- a/src/share/vm/classfile/vmSymbols.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -300,7 +300,6 @@ \ /* Support for JVMCI */ \ template(java_util_BitSet, "java/util/BitSet") \ - JVMCI_ONLY(template(jdk_internal_jvmci_debug_Debug, "jdk/internal/jvmci/debug/Debug")) \ JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotCompiledCode, "jdk/internal/jvmci/hotspot/HotSpotCompiledCode")) \ JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotCompiledCode_Comment, "jdk/internal/jvmci/hotspot/HotSpotCompiledCode$Comment")) \ JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotCompiledNmethod, "jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod")) \
--- a/src/share/vm/code/codeBlob.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/codeBlob.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -357,7 +357,7 @@ int _unpack_with_exception_in_tls; -#ifdef JVMCI +#if INCLUDE_JVMCI // (thomaswue) Offset when JVMCI calls uncommon_trap. int _uncommon_trap_offset; int _implicit_exception_uncommon_trap_offset; @@ -416,7 +416,7 @@ } address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; } -#ifdef JVMCI +#if INCLUDE_JVMCI // (thomaswue) Offset when JVMCI calls uncommon_trap. void set_uncommon_trap_offset(int offset) { _uncommon_trap_offset = offset;
--- a/src/share/vm/code/debugInfoRec.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/debugInfoRec.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -37,7 +37,7 @@ int _offset; // location in the stream of this scope int _length; // number of bytes in the stream int _hash; // hash of stream bytes (for quicker reuse) -#ifdef JVMCI +#if INCLUDE_JVMCI DebugInformationRecorder* _DIR; #endif @@ -54,7 +54,7 @@ DIR_Chunk(int offset, int length, DebugInformationRecorder* dir) { _offset = offset; _length = length; -#ifdef JVMCI +#if INCLUDE_JVMCI _DIR = dir; #endif unsigned int hash = 0; @@ -84,7 +84,7 @@ return NULL; } -#ifdef JVMCI +#if INCLUDE_JVMCI static int compare(DIR_Chunk* a, DIR_Chunk* b) { if (b->_hash > a->_hash) { return 1; @@ -138,7 +138,7 @@ _oop_recorder = oop_recorder; _all_chunks = new GrowableArray<DIR_Chunk*>(300); -#ifndef JVMCI +#if !INCLUDE_JVMCI _shared_chunks = new GrowableArray<DIR_Chunk*>(30); #endif _next_chunk = _next_chunk_limit = NULL; @@ -277,7 +277,7 @@ DIR_Chunk* ns = new(this) DIR_Chunk(stream_offset, stream_length, this); -#ifdef JVMCI +#if INCLUDE_JVMCI DIR_Chunk* match = _all_chunks->find_insert_binary<DIR_Chunk::compare>(ns); if (match != ns) { // Found an existing chunk
--- a/src/share/vm/code/debugInfoRec.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/debugInfoRec.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -163,7 +163,7 @@ // Scopes that have been described so far. GrowableArray<DIR_Chunk*>* _all_chunks; -#ifndef JVMCI +#if !INCLUDE_JVMCI GrowableArray<DIR_Chunk*>* _shared_chunks; #endif DIR_Chunk* _next_chunk;
--- a/src/share/vm/code/dependencies.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/dependencies.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -52,9 +52,9 @@ _oop_recorder = env->oop_recorder(); _log = env->log(); _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0); -#ifdef JVMCI +#if INCLUDE_JVMCI _using_dep_values = false; -#endif // JVMCI +#endif DEBUG_ONLY(_deps[end_marker] = NULL); for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) { _deps[i] = new(arena) GrowableArray<ciBaseObject*>(arena, 10, 0, 0); @@ -124,7 +124,7 @@ assert_common_2(call_site_target_value, call_site, method_handle); } -#ifdef JVMCI +#if INCLUDE_JVMCI Dependencies::Dependencies(Arena* arena, OopRecorder* oop_recorder, CompileLog* log) { _oop_recorder = oop_recorder; @@ -180,7 +180,7 @@ void Dependencies::assert_call_site_target_value(oop call_site, oop method_handle) { assert_common_2(call_site_target_value, DepValue(_oop_recorder, JNIHandles::make_local(call_site)), DepValue(_oop_recorder, JNIHandles::make_local(method_handle))); } -#endif // JVMCI +#endif // INCLUDE_JVMCI // Helper function. If we are adding a new dep. under ctxk2, @@ -294,7 +294,7 @@ deps->append(x2); } -#ifdef JVMCI +#if INCLUDE_JVMCI bool Dependencies::maybe_merge_ctxk(GrowableArray<DepValue>* deps, int ctxk_i, DepValue ctxk2_dv) { Klass* ctxk1 = deps->at(ctxk_i).as_klass(_oop_recorder); @@ -364,7 +364,7 @@ deps->append(x0); deps->append(x1); } -#endif // JVMCI +#endif // INCLUDE_JVMCI /// Support for encoding dependencies into an nmethod: @@ -392,7 +392,7 @@ static int sort_dep_arg_3(ciBaseObject** p1, ciBaseObject** p2) { return sort_dep(p1, p2, 3); } -#ifdef JVMCI +#if INCLUDE_JVMCI // metadata deps are sorted before object deps static int sort_dep_value(Dependencies::DepValue* p1, Dependencies::DepValue* p2, int narg) { for (int i = 0; i < narg; i++) { @@ -407,10 +407,10 @@ { return sort_dep_value(p1, p2, 2); } static int sort_dep_value_arg_3(Dependencies::DepValue* p1, Dependencies::DepValue* p2) { return sort_dep_value(p1, p2, 3); } -#endif // JVMCI +#endif // INCLUDE_JVMCI void Dependencies::sort_all_deps() { -#ifdef JVMCI +#if INCLUDE_JVMCI if (_using_dep_values) { for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; @@ -425,7 +425,7 @@ } return; } -#endif // JVMCI +#endif for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray<ciBaseObject*>* deps = _deps[dept]; @@ -441,7 +441,7 @@ size_t Dependencies::estimate_size_in_bytes() { size_t est_size = 100; -#ifdef JVMCI +#if INCLUDE_JVMCI if (_using_dep_values) { for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; @@ -450,7 +450,7 @@ } return est_size; } -#endif // JVMCI +#endif for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray<ciBaseObject*>* deps = _deps[dept]; @@ -490,7 +490,7 @@ // cast is safe, no deps can overflow INT_MAX CompressedWriteStream bytes((int)estimate_size_in_bytes()); -#ifdef JVMCI +#if INCLUDE_JVMCI if (_using_dep_values) { for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; @@ -520,7 +520,7 @@ } } } else { -#endif // JVMCI +#endif for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray<ciBaseObject*>* deps = _deps[dept]; @@ -554,9 +554,9 @@ } } } -#ifdef JVMCI +#if INCLUDE_JVMCI } -#endif // JVMCI +#endif // write a sentinel byte to mark the end bytes.write_byte(end_marker);
--- a/src/share/vm/code/dependencies.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/dependencies.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -200,7 +200,7 @@ static void check_valid_dependency_type(DepType dept); -#ifdef JVMCI +#if INCLUDE_JVMCI // A Metadata* or object value recorded in an OopRecorder class DepValue VALUE_OBJ_CLASS_SPEC { private: @@ -249,7 +249,7 @@ // State for writing a new set of dependencies: GrowableArray<int>* _dep_seen; // (seen[h->ident] & (1<<dept)) GrowableArray<ciBaseObject*>* _deps[TYPE_LIMIT]; -#ifdef JVMCI +#if INCLUDE_JVMCI bool _using_dep_values; GrowableArray<DepValue>* _dep_values[TYPE_LIMIT]; #endif @@ -271,7 +271,7 @@ return (seen & (1<<dept)) != 0; } -#ifdef JVMCI +#if INCLUDE_JVMCI bool note_dep_seen(int dept, DepValue x) { assert(dept < BitsPerInt, "oops"); // place metadata deps at even indexes, object deps at odd indexes @@ -286,7 +286,7 @@ bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps, int ctxk_i, ciKlass* ctxk); -#ifdef JVMCI +#if INCLUDE_JVMCI bool maybe_merge_ctxk(GrowableArray<DepValue>* deps, int ctxk_i, DepValue ctxk); #endif @@ -311,9 +311,9 @@ Dependencies(ciEnv* env) { initialize(env); } -#ifdef JVMCI +#if INCLUDE_JVMCI Dependencies(Arena* arena, OopRecorder* oop_recorder, CompileLog* log); -#endif // JVMCI +#endif private: // Check for a valid context type. @@ -346,7 +346,7 @@ void assert_has_no_finalizable_subclasses(ciKlass* ctxk); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); -#ifdef JVMCI +#if INCLUDE_JVMCI private: static void check_ctxk(Klass* ctxk) { assert(ctxk->oop_is_instance(), "java types only");
--- a/src/share/vm/code/nmethod.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/nmethod.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -61,7 +61,7 @@ #ifdef SHARK #include "shark/sharkCompiler.hpp" #endif -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciJavaAccess.hpp" #endif @@ -253,7 +253,7 @@ #ifdef COMPILER2 static java_nmethod_stats_struct c2_java_nmethod_stats; #endif -#ifdef JVMCI +#if INCLUDE_JVMCI static java_nmethod_stats_struct jvmci_java_nmethod_stats; #endif #ifdef SHARK @@ -279,7 +279,7 @@ c2_java_nmethod_stats.note_nmethod(nm); } else #endif -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm->is_compiled_by_jvmci()) { jvmci_java_nmethod_stats.note_nmethod(nm); } else @@ -574,7 +574,7 @@ #if INCLUDE_RTM_OPT _rtm_state = NoRTM; #endif -#ifdef JVMCI +#if INCLUDE_JVMCI _jvmci_installed_code = NULL; _speculation_log = NULL; #endif @@ -672,7 +672,7 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level -#ifdef JVMCI +#if INCLUDE_JVMCI , Handle installed_code, Handle speculationLog #endif @@ -699,7 +699,7 @@ nul_chk_table, compiler, comp_level -#ifdef JVMCI +#if INCLUDE_JVMCI , installed_code, speculationLog #endif @@ -935,7 +935,7 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level -#ifdef JVMCI +#if INCLUDE_JVMCI , Handle installed_code, Handle speculation_log #endif @@ -963,7 +963,7 @@ _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); -#ifdef JVMCI +#if INCLUDE_JVMCI _jvmci_installed_code = installed_code(); _speculation_log = (instanceOop)speculation_log(); @@ -996,7 +996,7 @@ _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); } else { _deoptimize_mh_offset = -1; -#ifdef JVMCI +#if INCLUDE_JVMCI } #endif } @@ -1490,7 +1490,7 @@ // Unregister must be done before the state change Universe::heap()->unregister_nmethod(this); -#ifdef JVMCI +#if INCLUDE_JVMCI // The method can only be unloaded after the pointer to the installed code // Java wrapper is no longer alive. Here we need to clear out this weak // reference to the dead object. Nulling out the reference has to happen @@ -1667,7 +1667,7 @@ } else { assert(state == not_entrant, "other cases may need to be handled differently"); } -#ifdef JVMCI +#if INCLUDE_JVMCI if (_jvmci_installed_code != NULL) { // Break the link between nmethod and InstalledCode such that the nmethod can subsequently be flushed safely. InstalledCode::set_address(_jvmci_installed_code, 0); @@ -1979,7 +1979,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI // Follow JVMCI method BarrierSet* bs = Universe::heap()->barrier_set(); if (_jvmci_installed_code != NULL) { @@ -2116,7 +2116,7 @@ unloading_occurred = true; } -#ifdef JVMCI +#if INCLUDE_JVMCI // Follow JVMCI method if (_jvmci_installed_code != NULL) { if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) { @@ -2205,7 +2205,7 @@ return postponed; } -#ifdef JVMCI +#if INCLUDE_JVMCI // Follow JVMCI method BarrierSet* bs = Universe::heap()->barrier_set(); if (_jvmci_installed_code != NULL) { @@ -2415,7 +2415,7 @@ // (See comment above.) } -#ifdef JVMCI +#if INCLUDE_JVMCI if (_jvmci_installed_code != NULL) { f->do_oop((oop*) &_jvmci_installed_code); } @@ -2628,9 +2628,9 @@ // When using JVMCI the address might be off by the size of a call instruction. bool nmethod::is_deopt_entry(address pc) { return pc == deopt_handler_begin() -#ifdef JVMCI +#if INCLUDE_JVMCI || pc == (deopt_handler_begin() + NativeCall::instruction_size) -#endif // JVMCI +#endif ; } @@ -3533,7 +3533,7 @@ #ifdef COMPILER2 c2_java_nmethod_stats.print_nmethod_stats("C2"); #endif -#ifdef JVMCI +#if INCLUDE_JVMCI jvmci_java_nmethod_stats.print_nmethod_stats("JVMCI"); #endif #ifdef SHARK @@ -3548,7 +3548,7 @@ if (xtty != NULL) xtty->tail("statistics"); } -#ifdef JVMCI +#if INCLUDE_JVMCI char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) { if (!this->is_compiled_by_jvmci()) { return NULL;
--- a/src/share/vm/code/nmethod.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/nmethod.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -126,7 +126,7 @@ int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method jmethodID _jmethod_id; // Cache of method()->jmethod_id() -#ifdef JVMCI +#if INCLUDE_JVMCI // Needed to keep nmethods alive that are not the default nmethod for the associated Method. oop _jvmci_installed_code; oop _speculation_log; @@ -299,7 +299,7 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level -#ifdef JVMCI +#if INCLUDE_JVMCI , Handle installed_code, Handle speculation_log #endif @@ -340,7 +340,7 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level -#ifdef JVMCI +#if INCLUDE_JVMCI , Handle installed_code = Handle(), Handle speculation_log = Handle() #endif @@ -626,7 +626,7 @@ // Evolution support. We make old (discarded) compiled methods point to new Method*s. void set_method(Method* method) { _method = method; } -#ifdef JVMCI +#if INCLUDE_JVMCI oop jvmci_installed_code() { return _jvmci_installed_code ; } char* jvmci_installed_code_name(char* buf, size_t buflen); void set_jvmci_installed_code(oop installed_code) { _jvmci_installed_code = installed_code; }
--- a/src/share/vm/code/scopeDesc.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/code/scopeDesc.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -226,7 +226,7 @@ } } -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) { tty->print_cr("Objects"); for (int i = 0; i < _objects->length(); i++) { @@ -237,7 +237,7 @@ tty->cr(); } } -#endif // COMPILER2 || JVMCI +#endif // COMPILER2 || INCLUDE_JVMCI } #endif
--- a/src/share/vm/compiler/abstractCompiler.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/abstractCompiler.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -29,7 +29,7 @@ typedef void (*initializer)(void); -#ifdef JVMCI +#if INCLUDE_JVMCI // Per-compiler statistics class CompilerStatistics VALUE_OBJ_CLASS_SPEC { friend class VMStructs; @@ -89,7 +89,7 @@ private: Type _type; -#ifdef JVMCI +#if INCLUDE_JVMCI CompilerStatistics _stats; #endif @@ -136,7 +136,7 @@ ShouldNotReachHere(); } -#ifdef JVMCI +#if INCLUDE_JVMCI CompilerStatistics* stats() { return &_stats; } #endif };
--- a/src/share/vm/compiler/compileBroker.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -49,7 +49,7 @@ #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciCompiler.hpp" #ifdef COMPILERJVMCI #include "jvmci/jvmciRuntime.hpp" @@ -916,7 +916,7 @@ // Set the interface to the current compiler(s). int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple); int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization); -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCICompiler* jvmci = new JVMCICompiler(); #endif @@ -2473,7 +2473,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI void CompileBroker::print_times(AbstractCompiler* comp) { CompilerStatistics* stats = comp->stats(); tty->print_cr(" %s {speed: %d bytes/s; standard: %6.3f s, %d bytes, %d methods; osr: %6.3f s, %d bytes, %d methods; nmethods_size: %d bytes; nmethods_code_size: %d bytes}", @@ -2486,7 +2486,7 @@ #endif void CompileBroker::print_times(bool per_compiler, bool aggregate) { -#ifdef JVMCI +#if INCLUDE_JVMCI elapsedTimer standard_compilation; elapsedTimer total_compilation; elapsedTimer osr_compilation;
--- a/src/share/vm/compiler/compileBroker.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/compileBroker.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -456,7 +456,7 @@ // Redefine Classes support static void mark_on_stack(); -#ifdef JVMCI +#if INCLUDE_JVMCI // Print curent compilation time stats for a given compiler static void print_times(AbstractCompiler* comp); #endif
--- a/src/share/vm/compiler/disassembler.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/disassembler.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -529,7 +529,7 @@ nm->method()->method_holder()->name()->print_symbol_on(env.output()); env.output()->print("."); nm->method()->name()->print_symbol_on(env.output()); -#ifdef JVMCI +#if INCLUDE_JVMCI { char buffer[O_BUFLEN]; char* jvmciName = nm->jvmci_installed_code_name(buffer, O_BUFLEN);
--- a/src/share/vm/compiler/oopMap.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/oopMap.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -319,9 +319,9 @@ COMPILER1_PRESENT(ShouldNotReachHere();) COMPILERJVMCI_PRESENT(ShouldNotReachHere();) #endif // TIERED -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI DerivedPointerTable::add(derived, base); -#endif // COMPILER2 +#endif // COMPILER2 || JVMCI } @@ -509,12 +509,12 @@ COMPILER1_PRESENT(return false); COMPILERJVMCI_PRESENT(return false); #endif // !TIERED -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI OopMapStream oms((OopMap*)this,OopMapValue::derived_oop_value); return oms.is_done(); #else return false; -#endif // COMPILER2 +#endif // COMPILER2 || JVMCI } #endif //PRODUCT @@ -581,7 +581,7 @@ //------------------------------DerivedPointerTable--------------------------- -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI class DerivedPointerEntry : public CHeapObj<mtCompiler> { private: @@ -674,4 +674,4 @@ _active = false; } -#endif // COMPILER2 +#endif // COMPILER2 || JVMCI
--- a/src/share/vm/compiler/oopMap.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/compiler/oopMap.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -283,7 +283,7 @@ // oops, it is filled in with references to all locations that contains a // derived oop (assumed to be very few). When the GC is complete, the derived // pointers are updated based on their base pointers new value and an offset. -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI class DerivedPointerTable : public AllStatic { friend class VMStructs; private: @@ -319,6 +319,6 @@ } } }; -#endif // COMPILER2 +#endif // COMPILER2 || JVMCI #endif // SHARE_VM_COMPILER_OOPMAP_HPP
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -2547,7 +2547,9 @@ if (UseAdaptiveSizePolicy) { size_policy()->ms_collection_begin(); } - COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTableDeactivate dpt_deact; +#endif HandleMark hm; // Discard invalid handles created during verification @@ -3021,7 +3023,9 @@ // way with the marking information used by GC. NoRefDiscovery no_discovery(ref_processor()); - COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTableDeactivate dpt_deact; +#endif // Clear any marks from a previous round verification_mark_bm()->clear_all(); @@ -3729,7 +3733,9 @@ } { - COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTableDeactivate dpt_deact; +#endif if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) { // The parallel version. FlexibleWorkGang* workers = gch->workers(); @@ -5119,7 +5125,9 @@ } { - COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTableDeactivate dpt_deact; +#endif // Note on the role of the mod union table: // Since the marker in "markFromRoots" marks concurrently with
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1333,7 +1333,9 @@ check_bitmaps("Full GC Start"); pre_full_gc_dump(gc_timer); - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif // Disable discovery and empty the discovered lists // for the CM ref processor. @@ -1393,7 +1395,9 @@ // not been removed from the discovered lists. ref_processor_stw()->enqueue_discovered_references(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif MemoryService::track_memory_usage(); @@ -3603,8 +3607,9 @@ // FIXME: what is this about? // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" // is set. - COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), - "derived pointer present")); +#if defined(COMPILER2) || INCLUDE_JVMCI + assert(DerivedPointerTable::is_empty(), "derived pointer present"); +#endif // always_do_update_barrier = true; resize_all_tlabs(); @@ -3938,7 +3943,9 @@ verify_before_gc(); check_bitmaps("GC Start"); - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif // Please see comment in g1CollectedHeap.hpp and // G1CollectedHeap::ref_processing_init() to see how @@ -5989,7 +5996,9 @@ enqueue_discovered_references(n_workers); redirty_logged_cards(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif } void G1CollectedHeap::free_region(HeapRegion* hr,
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -89,8 +89,10 @@ mark_sweep_phase2(); +#if defined(COMPILER2) || INCLUDE_JVMCI // Don't add any more derived pointers during phase3 - COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); + DerivedPointerTable::set_active(false); +#endif mark_sweep_phase3(); @@ -170,7 +172,9 @@ if (VerifyDuringGC) { HandleMark hm; // handle scope - COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTableDeactivate dpt_deact; +#endif Universe::heap()->prepare_for_verify(); // Note: we can verify only the heap here. When an object is // marked, the previous value of the mark word (including
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -194,7 +194,9 @@ allocate_stacks(); - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); ref_processor()->setup_policy(clear_all_softrefs); @@ -203,9 +205,11 @@ mark_sweep_phase2(); +#if defined(COMPILER2) || INCLUDE_JVMCI // Don't add any more derived pointers during phase3 - COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); - COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); + assert(DerivedPointerTable::is_active(), "Sanity"); + DerivedPointerTable::set_active(false); +#endif mark_sweep_phase3(); @@ -254,7 +258,9 @@ CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif ref_processor()->enqueue_discovered_references(NULL);
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1068,7 +1068,9 @@ CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif ref_processor()->enqueue_discovered_references(NULL); @@ -2068,7 +2070,9 @@ CodeCache::gc_prologue(); Threads::gc_prologue(); - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); ref_processor()->setup_policy(maximum_heap_compaction); @@ -2082,8 +2086,10 @@ && gc_cause == GCCause::_java_lang_system_gc; summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); - COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); - COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); +#if defined(COMPILER2) || INCLUDE_JVMCI + assert(DerivedPointerTable::is_active(), "Sanity"); + DerivedPointerTable::set_active(false); +#endif // adjust_roots() updates Universe::_intArrayKlassObj which is // needed by the compaction for filling holes in the dense prefix.
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -360,7 +360,9 @@ } save_to_space_top_before_gc(); - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif reference_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); reference_processor()->setup_policy(false); @@ -633,7 +635,9 @@ assert(young_gen->to_space()->is_empty(), "to space should be empty now"); } - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
--- a/src/share/vm/gc_interface/collectedHeap.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/gc_interface/collectedHeap.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -217,7 +217,7 @@ #ifdef COMPILER2 _defer_initial_card_mark = ReduceInitialCardMarks && can_elide_tlab_store_barriers() && (DeferInitialCardMark || card_mark_must_follow_store()); -#elif defined JVMCI +#elif INCLUDE_JVMCI _defer_initial_card_mark = JVMCIDeferredInitBarriers && can_elide_tlab_store_barriers() && (DeferInitialCardMark || card_mark_must_follow_store()); #else @@ -527,7 +527,7 @@ " to threads list is doomed to failure!"); for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) { if (use_tlab) thread->tlab().make_parsable(retire_tlabs); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // The deferred store barriers must all have been flushed to the // card-table (or other remembered set structure) before GC starts // processing the card-table (or other remembered set).
--- a/src/share/vm/interpreter/interpreter.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/interpreter/interpreter.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -409,7 +409,7 @@ address AbstractInterpreter::deopt_reexecute_entry(Method* method, address bcp) { assert(method->contains(bcp), "just checkin'"); Bytecodes::Code code = Bytecodes::java_code_at(method, bcp); -#if defined(COMPILER1) || defined(JVMCI) +#if defined(COMPILER1) || INCLUDE_JVMCI if(code == Bytecodes::_athrow ) { return Interpreter::rethrow_exception_entry(); }
--- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -475,7 +475,7 @@ } } while (should_repeat == true); -#ifdef JVMCI +#if INCLUDE_JVMCI if (h_method->method_data() != NULL) { ResourceMark rm(thread); ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci, NULL);
--- a/src/share/vm/interpreter/linkResolver.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/interpreter/linkResolver.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -125,11 +125,11 @@ private: static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS); -#ifdef JVMCI +#if INCLUDE_JVMCI public: #endif static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); -#ifdef JVMCI +#if INCLUDE_JVMCI private: #endif static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); @@ -145,12 +145,12 @@ static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); -#ifdef JVMCI +#if INCLUDE_JVMCI public: #endif static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS); static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); -#ifdef JVMCI +#if INCLUDE_JVMCI private: #endif
--- a/src/share/vm/jvmci/jvmciEnv.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/jvmci/jvmciEnv.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "jvmci/jvmciEnv.hpp" +#include "classfile/javaAssertions.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/scopeDesc.hpp" @@ -435,7 +436,7 @@ // or if we don't know whether it has changed (i.e., env == NULL). // In debug mode, always check dependencies. bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); - bool verify_deps = env == NULL || trueInDebug || Debug::ENABLED(); + bool verify_deps = env == NULL || trueInDebug || JavaAssertions::enabled(SystemDictionary::HotSpotInstalledCode_klass()->name()->as_C_string(), true); if (!counter_changed && !verify_deps) { return JVMCIEnv::ok; }
--- a/src/share/vm/jvmci/jvmciJavaAccess.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -256,10 +256,8 @@ long_field(HotSpotStackFrameReference, metaspaceMethod) \ objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;") \ typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z") \ - end_class \ - start_class(Debug) \ - static_boolean_field(Debug, ENABLED) \ - end_class \ + end_class + \ /* end*/ #define START_CLASS(name) \
--- a/src/share/vm/memory/genCollectedHeap.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/memory/genCollectedHeap.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -452,7 +452,9 @@ } Universe::verify(" VerifyBeforeGC:"); } - COMPILER2_PRESENT(DerivedPointerTable::clear()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::clear(); +#endif if (!must_restore_marks_for_biased_locking && _gens[i]->performs_in_place_marking()) { @@ -512,7 +514,9 @@ } } - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); +#if defined(COMPILER2) || INCLUDE_JVMCI + DerivedPointerTable::update_pointers(); +#endif _gens[i]->stat_record()->accumulated_time.stop(); @@ -1220,7 +1224,7 @@ }; void GenCollectedHeap::gc_epilogue(bool full) { -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI assert(DerivedPointerTable::is_empty(), "derived pointer present"); size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr())); guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
--- a/src/share/vm/memory/genMarkSweep.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/memory/genMarkSweep.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -96,8 +96,10 @@ mark_sweep_phase2(); // Don't add any more derived pointers during phase3 - COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); - COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); +#if defined(COMPILER2) || INCLUDE_JVMCI + assert(DerivedPointerTable::is_active(), "Sanity"); + DerivedPointerTable::set_active(false); +#endif mark_sweep_phase3(level);
--- a/src/share/vm/memory/referenceProcessor.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/memory/referenceProcessor.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -57,7 +57,7 @@ java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock); _always_clear_soft_ref_policy = new AlwaysClearPolicy(); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI _default_soft_ref_policy = new LRUMaxHeapPolicy(); #else _default_soft_ref_policy = new LRUCurrentHeapPolicy();
--- a/src/share/vm/oops/instanceKlass.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -61,7 +61,7 @@ #include "services/threadService.hpp" #include "utilities/dtrace.hpp" #include "utilities/macros.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "classfile/javaAssertions.hpp" #include "jvmci/jvmciRuntime.hpp" #endif
--- a/src/share/vm/oops/method.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/oops/method.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -218,7 +218,7 @@ Thread* myThread = Thread::current(); methodHandle h_this(myThread, this); -#if defined(ASSERT) && !defined(JVMCI) +#if defined(ASSERT) && !INCLUDE_JVMCI bool has_capability = myThread->is_VM_thread() || myThread->is_ConcurrentGC_thread() || myThread->is_GC_task_thread();
--- a/src/share/vm/oops/methodData.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/oops/methodData.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -420,7 +420,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { ReceiverTypeData::clean_weak_klass_links(is_alive_cl); for (uint row = 0; row < method_row_limit(); row++) { @@ -440,7 +440,7 @@ } } } -#endif // JVMCI +#endif // INCLUDE_JVMCI #ifndef PRODUCT void ReceiverTypeData::print_receiver_data_on(outputStream* st) const { @@ -449,7 +449,7 @@ for (row = 0; row < row_limit(); row++) { if (receiver(row) != NULL) entries++; } -#ifdef JVMCI +#if INCLUDE_JVMCI st->print_cr("count(%u) nonprofiled_count(%u) entries(%u)", count(), nonprofiled_count(), entries); #else st->print_cr("count(%u) entries(%u)", count(), entries); @@ -473,7 +473,7 @@ print_receiver_data_on(st); } -#ifdef JVMCI +#if INCLUDE_JVMCI void VirtualCallData::print_method_data_on(outputStream* st) const { uint row; int entries = 0; @@ -501,7 +501,7 @@ void VirtualCallData::print_data_on(outputStream* st, const char* extra) const { print_shared(st, "VirtualCallData", extra); print_receiver_data_on(st); -#ifdef JVMCI +#if INCLUDE_JVMCI print_method_data_on(st); #endif } @@ -740,7 +740,7 @@ } int MethodData::bytecode_cell_count(Bytecodes::Code code) { -#if defined(COMPILER1) && !(defined(COMPILER2) || defined(JVMCI)) +#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI) return no_profile_data; #else switch (code) { @@ -869,7 +869,7 @@ return false; } -#ifdef JVMCI +#if INCLUDE_JVMCI int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) { if (!ProfileTraps) return 0; @@ -963,7 +963,7 @@ // the segment in bytes. int MethodData::initialize_data(BytecodeStream* stream, int data_index) { -#if defined(COMPILER1) && !(defined(COMPILER2) || defined(JVMCI)) +#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI) return 0; #else int cell_count = -1; @@ -1236,7 +1236,7 @@ _num_blocks = 0; _would_profile = unknown; -#ifdef JVMCI +#if INCLUDE_JVMCI _jvmci_ir_size = 0; #endif
--- a/src/share/vm/oops/methodData.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/oops/methodData.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -543,7 +543,7 @@ // saw a null operand (cast/aastore/instanceof) null_seen_flag = DataLayout::first_flag + 0 -#ifdef JVMCI +#if INCLUDE_JVMCI // bytecode threw any exception , exception_seen_flag = null_seen_flag + 1 #endif @@ -570,7 +570,7 @@ bool null_seen() { return flag_at(null_seen_flag); } void set_null_seen() { set_flag_at(null_seen_flag); } -#ifdef JVMCI +#if INCLUDE_JVMCI // true if an exception was thrown at the specific BCI bool exception_seen() { return flag_at(exception_seen_flag); } void set_exception_seen() { set_flag_at(exception_seen_flag); } @@ -1179,7 +1179,7 @@ class ReceiverTypeData : public CounterData { protected: enum { -#ifdef JVMCI +#if INCLUDE_JVMCI // Description of the different counters // ReceiverTypeData for instanceof/checkcast/aastore: // C1/C2: count is incremented on type overflow and decremented for failed type checks @@ -1271,7 +1271,7 @@ set_count(0); set_receiver(row, NULL); set_receiver_count(row, 0); -#ifdef JVMCI +#if INCLUDE_JVMCI if (!this->is_VirtualCallData()) { // if this is a ReceiverTypeData for JVMCI, the nonprofiled_count // must also be reset (see "Description of the different counters" above) @@ -1287,7 +1287,7 @@ static ByteSize receiver_count_offset(uint row) { return cell_offset(receiver_count_cell_index(row)); } -#ifdef JVMCI +#if INCLUDE_JVMCI static ByteSize nonprofiled_receiver_count_offset() { return cell_offset(nonprofiled_count_off_set); } @@ -1386,7 +1386,7 @@ } #endif // CC_INTERP -#ifdef JVMCI +#if INCLUDE_JVMCI static ByteSize method_offset(uint row) { return cell_offset(method_cell_index(row)); } @@ -1442,7 +1442,7 @@ #endif #ifndef PRODUCT -#ifdef JVMCI +#if INCLUDE_JVMCI void print_method_data_on(outputStream* st) const; #endif void print_data_on(outputStream* st, const char* extra = NULL) const; @@ -2210,7 +2210,7 @@ enum WouldProfile {unknown, no_profile, profile}; WouldProfile _would_profile; -#ifdef JVMCI +#if INCLUDE_JVMCI // Support for HotSpotMethodData.setCompiledIRSize(int) int _jvmci_ir_size; #endif
--- a/src/share/vm/precompiled/precompiled.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/precompiled/precompiled.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -295,9 +295,9 @@ # include "c1/c1_ValueType.hpp" # include "c1/c1_globals.hpp" #endif // COMPILER1 -#ifdef JVMCI +#if INCLUDE_JVMCI # include "jvmci/jvmciGlobals.hpp" -#endif // JVMCI +#endif // INCLUDE_JVMCI #if INCLUDE_ALL_GCS # include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp" # include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
--- a/src/share/vm/prims/jni.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/prims/jni.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -33,7 +33,7 @@ #include "classfile/vmSymbols.hpp" #include "interpreter/linkResolver.hpp" #include "utilities/macros.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciCompiler.hpp" #include "jvmci/jvmciRuntime.hpp" #endif @@ -5209,7 +5209,7 @@ *vm = (JavaVM *)(&main_vm); *(JNIEnv**)penv = thread->jni_environment(); -#if defined(JVMCI) +#if INCLUDE_JVMCI // We turn off CompileTheWorld so that compilation requests are not ignored during bootstrap or that JVMCI can be compiled by C1/C2. bool doCTW = CompileTheWorld; CompileTheWorld = false; @@ -5220,14 +5220,14 @@ if (FLAG_IS_DEFAULT(BootstrapJVMCI) ? !TieredCompilation : BootstrapJVMCI) { JVMCICompiler::instance()->bootstrap(); } -#elif defined(JVMCI) +#elif INCLUDE_JVMCI if (doCTW) { // required for hosted CTW. CompilationPolicy::completed_vm_startup(); } #endif -#if defined(JVMCI) +#if INCLUDE_JVMCI if (doCTW) { JVMCICompiler::instance()->compile_the_world(); }
--- a/src/share/vm/prims/jvm.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/prims/jvm.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -383,7 +383,7 @@ const char* compiler_name = "HotSpot " CSIZE "Client Compiler"; #elif defined(COMPILER2) const char* compiler_name = "HotSpot " CSIZE "Server Compiler"; -#elif defined(JVMCI) +#elif INCLUDE_JVMCI const char* compiler_name = "HotSpot " CSIZE "JVMCI Compiler"; #else const char* compiler_name = "";
--- a/src/share/vm/prims/nativeLookup.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/prims/nativeLookup.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -126,7 +126,7 @@ void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls); void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass); void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass); -#ifdef JVMCI +#if INCLUDE_JVMCI void JNICALL JVM_InitJVMCIClassLoader(JNIEnv *env, jclass c, jobject loader); void JNICALL JVM_InitializeJVMCINatives(JNIEnv *env, jclass compilerToVMClass); jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c); @@ -143,7 +143,7 @@ { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) }, -#ifdef JVMCI +#if INCLUDE_JVMCI { CC"Java_jdk_internal_jvmci_service_JVMCIClassLoaderFactory_init", NULL, FN_PTR(JVM_InitJVMCIClassLoader) }, { CC"Java_jdk_internal_jvmci_runtime_JVMCI_initializeRuntime", NULL, FN_PTR(JVM_GetJVMCIRuntime) }, { CC"Java_jdk_internal_jvmci_service_Services_getServiceImpls", NULL, FN_PTR(JVM_GetJVMCIServiceImpls) },
--- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -375,13 +375,7 @@ } else if ((this->*p)(i, b, cur_level)) { #ifdef COMPILERJVMCI // Since JVMCI takes a while to warm up, its queue inevitably backs up during - // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root - // compilation method and all potential inlinees have mature profiles (which - // includes type profiling). If it sees immature profiles, JVMCI's inliner - // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to - // exploring/inlining too many graphs). Since a rewrite of the inliner is - // in progress, we simply disable the dialing back heuristic for now and will - // revisit this decision once the new inliner is completed. + // early VM execution. next_level = CompLevel_full_profile; #else // C1-generated fully profiled code is about 30% slower than the limited profile
--- a/src/share/vm/runtime/arguments.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/arguments.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -44,7 +44,7 @@ #include "utilities/macros.hpp" #include "utilities/stringUtils.hpp" #include "utilities/taskqueue.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciRuntime.hpp" #endif #ifdef TARGET_OS_FAMILY_linux @@ -98,7 +98,7 @@ int Arguments::_num_jvm_flags = 0; char** Arguments::_jvm_args_array = NULL; int Arguments::_num_jvm_args = 0; -#ifdef JVMCI +#if INCLUDE_JVMCI char** Arguments::_jvmci_args_array = NULL; int Arguments::_num_jvmci_args = 0; #endif @@ -217,7 +217,7 @@ // Set OS specific system properties values os::init_system_properties_values(); -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCIRuntime::parse_properties(&_system_properties); #endif } @@ -817,7 +817,7 @@ void Arguments::build_jvm_flags(const char* arg) { add_string(&_jvm_flags_array, &_num_jvm_flags, arg); } -#ifdef JVMCI +#if INCLUDE_JVMCI void Arguments::add_jvmci_arg(const char* arg) { add_string(&_jvmci_args_array, &_num_jvmci_args, arg); } @@ -1127,7 +1127,7 @@ } } -#if defined(COMPILER2) || defined(JVMCI) || defined(_LP64) || !INCLUDE_CDS +#if defined(COMPILER2) || INCLUDE_JVMCI || defined(_LP64) || !INCLUDE_CDS // Conflict: required to use shared spaces (-Xshare:on), but // incompatible command line options were chosen. @@ -1595,7 +1595,7 @@ void Arguments::set_ergonomics_flags() { select_gc(); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // Shared spaces work fine with other GCs but causes bytecode rewriting // to be disabled, which hurts interpreter performance and decreases // server performance. When -server is specified, keep the default off @@ -1679,7 +1679,7 @@ void Arguments::set_g1_gc_flags() { assert(UseG1GC, "Error"); -#if defined(COMPILER1) || defined(JVMCI) +#if defined(COMPILER1) || INCLUDE_JVMCI FastTLABRefill = false; #endif FLAG_SET_DEFAULT(ParallelGCThreads, @@ -2446,7 +2446,7 @@ } #endif } -#ifdef JVMCI +#if INCLUDE_JVMCI if (UseG1GC) { if (IgnoreUnrecognizedVMOptions) { FLAG_SET_CMDLINE(bool, UseG1GC, true); @@ -2783,7 +2783,7 @@ return JNI_ERR; } #endif // !INCLUDE_JVMTI -#if defined(JVMCI) +#if INCLUDE_JVMCI if (strcmp(name, "hprof") == 0) { FLAG_SET_CMDLINE(bool, JVMCIHProfEnabled, true); } @@ -2810,7 +2810,7 @@ return JNI_ERR; } #endif // !INCLUDE_JVMTI -#if defined(JVMCI) +#if INCLUDE_JVMCI if (valid_hprof_or_jdwp_agent(name, is_absolute_path)) { FLAG_SET_CMDLINE(bool, JVMCIHProfEnabled, true); } @@ -3389,7 +3389,7 @@ } } } -#ifdef JVMCI +#if INCLUDE_JVMCI else if (match_option(option, "-G:", &tail)) { // -G:XXX // Option for the JVMCI compiler. if (PrintVMOptions) { @@ -3615,7 +3615,7 @@ // This must be done after all -D arguments have been processed. scp_p->expand_endorsed(); -#ifdef JVMCI +#if INCLUDE_JVMCI if (!UseJVMCIClassLoader) { // Append lib/jvmci/*.jar to boot class path char jvmciDir[JVM_MAXPATHLEN]; @@ -4136,9 +4136,9 @@ #ifdef COMPILER1 || !UseFastLocking #endif // COMPILER1 -#ifdef JVMCI +#if INCLUDE_JVMCI || !JVMCIUseFastLocking -#endif // JVMCI +#endif ) { if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) { // flag set to true on command line; warn the user that they
--- a/src/share/vm/runtime/arguments.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/arguments.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -246,7 +246,7 @@ // an array containing all jvm arguments specified in the command line static char** _jvm_args_array; static int _num_jvm_args; -#ifdef JVMCI +#if INCLUDE_JVMCI // an array containing all JVMCI arguments specified in the command line static char** _jvmci_args_array; static int _num_jvmci_args; @@ -410,7 +410,7 @@ // methods to build strings from individual args static void build_jvm_args(const char* arg); static void build_jvm_flags(const char* arg); -#ifdef JVMCI +#if INCLUDE_JVMCI static void add_jvmci_arg(const char* arg); #endif static void add_string(char*** bldarray, int* count, const char* arg); @@ -492,7 +492,7 @@ // return a char* array containing all options static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_args_array() { return _jvm_args_array; } -#ifdef JVMCI +#if INCLUDE_JVMCI static char** jvmci_args_array() { return _jvmci_args_array; } static int num_jvmci_args() { return _num_jvmci_args; } #endif
--- a/src/share/vm/runtime/deoptimization.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -92,7 +92,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciRuntime.hpp" #include "jvmci/jvmciJavaAccess.hpp" #endif @@ -225,7 +225,7 @@ bool realloc_failures = false; -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // Reallocate the non-escaping objects and restore their fields. Then // relock objects if synchronization on them was eliminated. #ifdef COMPILER2 @@ -313,7 +313,7 @@ } } #endif // COMPILER2 -#endif // COMPILER2 || JVMCI +#endif // COMPILER2 || INCLUDE_JVMCI // Ensure that no safepoint is taken after pointers have been stored // in fields of rematerialized objects. If a safepoint occurs from here on @@ -321,7 +321,7 @@ No_Safepoint_Verifier no_safepoint; vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI if (realloc_failures) { pop_frames_failed_reallocs(thread, array); } @@ -776,7 +776,7 @@ } -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { Handle pending_exception(thread->pending_exception()); const char* exception_file = thread->exception_file(); @@ -1111,7 +1111,7 @@ } } #endif -#endif // COMPILER2 || JVMCI +#endif // COMPILER2 || INCLUDE_JVMCI vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) { Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); @@ -1171,7 +1171,7 @@ return array; } -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) { // Reallocation of some scalar replaced objects failed. Record // that we need to pop all the interpreter frames for the @@ -1361,7 +1361,7 @@ JRT_END -#if defined(COMPILER2) || defined(SHARK) || defined(JVMCI) +#if defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { @@ -1424,7 +1424,7 @@ thread->inc_in_deopt_handler(); // We need to update the map if we have biased locking. -#ifdef JVMCI +#if INCLUDE_JVMCI // (lstadler) JVMCI might need to get an exception from the stack, which in turn requires the register map to be valid RegisterMap reg_map(thread, true); #else @@ -1448,7 +1448,7 @@ DeoptReason reason = trap_request_reason(trap_request); DeoptAction action = trap_request_action(trap_request); -#ifdef JVMCI +#if INCLUDE_JVMCI int debug_id = trap_request_debug_id(trap_request); #endif jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1 @@ -1463,7 +1463,7 @@ if (TraceDeoptimization) { ttyLocker ttyl; tty->print_cr(" bci=%d pc=" INTPTR_FORMAT ", relative_pc=%d, method=%s" JVMCI_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string() -#ifdef JVMCI +#if INCLUDE_JVMCI , debug_id #endif ); @@ -1471,7 +1471,7 @@ methodHandle trap_method = trap_scope->method(); int trap_bci = trap_scope->bci(); -#ifdef JVMCI +#if INCLUDE_JVMCI oop speculation = thread->pending_failed_speculation(); if (nm->is_compiled_by_jvmci()) { if (speculation != NULL) { @@ -1534,7 +1534,7 @@ bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking ); methodHandle profiled_method; -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm->is_compiled_by_jvmci()) { profiled_method = nm->method(); } else { @@ -1604,7 +1604,7 @@ tty->print("Uncommon trap occurred in"); nm->method()->print_short_name(tty); tty->print(" compiler=%s compile_id=%d", nm->compiler() == NULL ? "" : nm->compiler()->name(), nm->compile_id()); -#ifdef JVMCI +#if INCLUDE_JVMCI oop installedCode = nm->jvmci_installed_code(); if (installedCode != NULL) { oop installedCodeName = NULL; @@ -1619,14 +1619,14 @@ } else if (nm->is_compiled_by_jvmci()) { tty->print(" (JVMCI: no installed code) "); } -#endif //JVMCI +#endif tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d" JVMCI_ONLY(" debug_id=%d"), fr.pc(), os::current_thread_id(), trap_reason_name(reason), trap_action_name(action), unloaded_class_index -#ifdef JVMCI +#if INCLUDE_JVMCI , debug_id #endif ); @@ -1764,7 +1764,7 @@ bool maybe_prior_trap = false; bool maybe_prior_recompile = false; pdata = query_update_method_data(trap_mdo, trap_bci, reason, true, -#ifdef JVMCI +#if INCLUDE_JVMCI nm->is_compiled_by_jvmci() && nm->is_osr_method(), #endif nm->method(), @@ -1913,7 +1913,7 @@ int trap_bci, Deoptimization::DeoptReason reason, bool update_total_trap_count, -#ifdef JVMCI +#if INCLUDE_JVMCI bool is_osr, #endif Method* compiled_method, @@ -1926,7 +1926,7 @@ uint this_trap_count = 0; if (update_total_trap_count) { uint idx = reason; -#ifdef JVMCI +#if INCLUDE_JVMCI if (is_osr) { idx += Reason_LIMIT; } @@ -2005,7 +2005,7 @@ query_update_method_data(trap_mdo, trap_bci, (DeoptReason)reason, update_total_counts, -#ifdef JVMCI +#if INCLUDE_JVMCI false, #endif NULL, @@ -2142,7 +2142,7 @@ "speculate_class_check", "rtm_state_change", "unstable_if" -#ifdef JVMCI +#if INCLUDE_JVMCI "aliasing", "transfer_to_interpreter", "not_compiled_exception_handler", @@ -2181,21 +2181,21 @@ jint unloaded_class_index = trap_request_index(trap_request); const char* reason = trap_reason_name(trap_request_reason(trap_request)); const char* action = trap_action_name(trap_request_action(trap_request)); -#ifdef JVMCI +#if INCLUDE_JVMCI int debug_id = trap_request_debug_id(trap_request); #endif size_t len; if (unloaded_class_index < 0) { len = jio_snprintf(buf, buflen, "reason='%s' action='%s'" JVMCI_ONLY(" debug_id='%d'"), reason, action -#ifdef JVMCI +#if INCLUDE_JVMCI ,debug_id #endif ); } else { len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'" JVMCI_ONLY(" debug_id='%d'"), reason, action, unloaded_class_index -#ifdef JVMCI +#if INCLUDE_JVMCI ,debug_id #endif ); @@ -2295,7 +2295,7 @@ if (xtty != NULL) xtty->tail("statistics"); } } -#else // COMPILER2 || SHARK || JVMCI +#else // COMPILER2 || SHARK || INCLUDE_JVMCI // Stubs for C1 only system. @@ -2331,4 +2331,4 @@ return buf; } -#endif // COMPILER2 || SHARK || JVMCI +#endif // COMPILER2 || SHARK || INCLUDE_JVMCI
--- a/src/share/vm/runtime/deoptimization.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/deoptimization.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -56,7 +56,7 @@ Reason_intrinsic, // saw unexpected operand to intrinsic (@bci) Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci) -#ifdef JVMCI +#if INCLUDE_JVMCI Reason_unreached0 = Reason_null_assert, Reason_type_checked_inlining = Reason_intrinsic, Reason_optimized_type_check = Reason_bimorphic, @@ -75,7 +75,7 @@ Reason_speculate_class_check, // saw unexpected object class from type speculation Reason_rtm_state_change, // rtm state change detected Reason_unstable_if, // a branch predicted always false was taken -#ifdef JVMCI +#if INCLUDE_JVMCI Reason_aliasing, // optimistic assumption about aliasing failed Reason_transfer_to_interpreter, // explicit transferToInterpreter() Reason_not_compiled_exception_handler, @@ -138,7 +138,7 @@ // executing in a particular CodeBlob if UseBiasedLocking is enabled static void revoke_biases_of_monitors(CodeBlob* cb); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI JVMCI_ONLY(public:) // Support for restoring non-escaping objects @@ -149,7 +149,7 @@ static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures); static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array); NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);) -#endif // COMPILER2 || JVMCI +#endif // COMPILER2 || INCLUDE_JVMCI public: static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures); @@ -395,7 +395,7 @@ int trap_bci, DeoptReason reason, bool update_total_trap_count, -#ifdef JVMCI +#if INCLUDE_JVMCI bool is_osr, #endif Method* compiled_method,
--- a/src/share/vm/runtime/frame.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/frame.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -734,7 +734,7 @@ nm->compile_id(), (nm->is_osr_method() ? "%" : ""), ((nm->compiler() != NULL) ? nm->compiler()->name() : ""), buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin()); -#ifdef JVMCI +#if INCLUDE_JVMCI char* jvmciName = nm->jvmci_installed_code_name(buf, buflen); if (jvmciName != NULL) { st->print(" (%s)", jvmciName); @@ -1313,7 +1313,9 @@ // make sure we have the right receiver type } } - COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");) +#if defined(COMPILER2) || INCLUDE_JVMCI + assert(DerivedPointerTable::is_empty(), "must be empty before verify"); +#endif oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false); }
--- a/src/share/vm/runtime/globals.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/globals.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -38,7 +38,7 @@ #ifdef COMPILER1 #include "c1/c1_globals.hpp" #endif -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciGlobals.hpp" #endif #ifdef COMPILER2 @@ -494,7 +494,7 @@ #ifdef COMPILER1 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) #endif -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, JVMCI_PD_DEVELOP_FLAG_STRUCT, JVMCI_PRODUCT_FLAG_STRUCT, JVMCI_PD_PRODUCT_FLAG_STRUCT, JVMCI_NOTPRODUCT_FLAG_STRUCT) #endif #ifdef COMPILER2
--- a/src/share/vm/runtime/globals_extension.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/globals_extension.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -86,7 +86,7 @@ #ifdef COMPILER1 C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_DIAGNOSTIC_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER) #endif -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER, JVMCI_PD_DEVELOP_FLAG_MEMBER, JVMCI_PRODUCT_FLAG_MEMBER, JVMCI_PD_PRODUCT_FLAG_MEMBER, JVMCI_NOTPRODUCT_FLAG_MEMBER) #endif #ifdef COMPILER2 @@ -180,7 +180,7 @@ C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE, C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE) #endif -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE, JVMCI_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE, JVMCI_PRODUCT_FLAG_MEMBER_WITH_TYPE,
--- a/src/share/vm/runtime/java.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/java.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -30,7 +30,7 @@ #include "compiler/compileBroker.hpp" #include "compiler/compilerOracle.hpp" #include "interpreter/bytecodeHistogram.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciCompiler.hpp" #include "jvmci/jvmciRuntime.hpp" #endif @@ -490,7 +490,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCIRuntime::shutdown(); #endif
--- a/src/share/vm/runtime/javaCalls.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/javaCalls.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -40,7 +40,7 @@ #include "runtime/signature.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciJavaAccess.hpp" #include "jvmci/jvmciRuntime.hpp" #endif @@ -343,7 +343,7 @@ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) -#ifdef JVMCI +#if INCLUDE_JVMCI nmethod* nm = args->alternative_target(); if (nm == NULL) { #endif @@ -353,7 +353,7 @@ args->verify(method, result->get_type(), thread); } else debug_only(args->verify(method, result->get_type(), thread)); -#ifdef JVMCI +#if INCLUDE_JVMCI } #else @@ -418,7 +418,7 @@ os::bang_stack_shadow_pages(); } -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm != NULL) { if (nm->is_alive()) { ((JavaThread*) THREAD)->set_jvmci_alternate_call_target(nm->verified_entry_point());
--- a/src/share/vm/runtime/javaCalls.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/javaCalls.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -100,7 +100,7 @@ int _size; int _max_size; bool _start_at_zero; // Support late setting of receiver -#ifdef JVMCI +#if INCLUDE_JVMCI nmethod* _alternative_target; // Nmethod that should be called instead of normal target #endif @@ -140,7 +140,7 @@ } } -#ifdef JVMCI +#if INCLUDE_JVMCI void set_alternative_target(nmethod* target) { _alternative_target = target; }
--- a/src/share/vm/runtime/os.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/os.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -1189,7 +1189,7 @@ "%/lib/jce.jar:" "%/lib/charsets.jar:" "%/lib/jfr.jar:" -#ifdef JVMCI +#if INCLUDE_JVMCI "%/lib/jvmci-service.jar:" #endif "%/classes";
--- a/src/share/vm/runtime/os.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/os.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -104,7 +104,7 @@ class os: AllStatic { friend class VMStructs; friend class MallocTracker; -#ifdef JVMCI +#if INCLUDE_JVMCI friend class Arguments; // need access to format_boot_path #endif
--- a/src/share/vm/runtime/rframe.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/rframe.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -152,7 +152,7 @@ void RFrame::print(const char* kind) { #ifndef PRODUCT -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI int cnt = top_method()->interpreter_invocation_count(); #else int cnt = top_method()->invocation_count();
--- a/src/share/vm/runtime/sharedRuntime.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -111,7 +111,7 @@ _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), "resolve_virtual_call"); _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call"); -#if defined(COMPILER2) || defined(JVMCI) +#if defined(COMPILER2) || INCLUDE_JVMCI // Vectors are generated only by C2 and JVMCI. bool support_wide = is_wide_vector(MaxVectorSize); if (support_wide) { @@ -488,7 +488,7 @@ // Reset method handle flag. thread->set_is_method_handle_return(false); -#ifdef JVMCI +#if INCLUDE_JVMCI // JVMCI's ExceptionHandlerStub expects the thread local exception PC to be clear // and other exception handler continuations do not read it thread->set_exception_pc(NULL); @@ -650,7 +650,7 @@ assert(nm != NULL, "must exist"); ResourceMark rm; -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm->is_compiled_by_jvmci()) { // lookup exception handler for this pc int catch_pco = ret_pc - nm->code_begin(); @@ -795,7 +795,7 @@ throw_and_post_jvmti_exception(thread, exception); JRT_END -#ifdef JVMCI +#if INCLUDE_JVMCI address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) { assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason"); thread->set_jvmci_implicit_exception_pc(pc); @@ -901,7 +901,7 @@ #ifndef PRODUCT _implicit_null_throws++; #endif -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) { // If there's no PcDesc then we'll die way down inside of // deopt instead of just getting normal error reporting, @@ -910,7 +910,7 @@ } else { #endif target_pc = nm->continuation_for_implicit_exception(pc); -#ifdef JVMCI +#if INCLUDE_JVMCI } #endif // If there's an unexpected fault, target_pc might be NULL, @@ -928,13 +928,13 @@ #ifndef PRODUCT _implicit_div0_throws++; #endif -#ifdef JVMCI +#if INCLUDE_JVMCI if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) { return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check); } else { #endif target_pc = nm->continuation_for_implicit_exception(pc); -#ifdef JVMCI +#if INCLUDE_JVMCI } #endif // If there's an unexpected fault, target_pc might be NULL, @@ -1013,7 +1013,7 @@ JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) -#ifdef JVMCI +#if INCLUDE_JVMCI if (!obj->klass()->has_finalizer()) { return; }
--- a/src/share/vm/runtime/sharedRuntime.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -193,7 +193,7 @@ static address continuation_for_implicit_exception(JavaThread* thread, address faulting_pc, ImplicitExceptionKind exception_kind); -#ifdef JVMCI +#if INCLUDE_JVMCI static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason); #endif
--- a/src/share/vm/runtime/sweeper.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/sweeper.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -458,14 +458,14 @@ class NMethodMarker: public StackObj { private: -#ifdef JVMCI +#if INCLUDE_JVMCI JavaThread* _thread; #else CompilerThread* _thread; #endif public: NMethodMarker(nmethod* nm) { -#ifdef JVMCI +#if INCLUDE_JVMCI _thread = JavaThread::current(); #else _thread = CompilerThread::current();
--- a/src/share/vm/runtime/thread.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/thread.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -29,7 +29,7 @@ #include "classfile/vmSymbols.hpp" #include "code/scopeDesc.hpp" #include "compiler/compileBroker.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "jvmci/jvmciCompiler.hpp" #include "jvmci/jvmciRuntime.hpp" #endif @@ -843,7 +843,7 @@ active_handles()->oops_do(f); // Do oop for ThreadShadow f->do_oop((oop*)&_pending_exception); -#ifdef JVMCI +#if INCLUDE_JVMCI f->do_oop((oop*)&_pending_failed_speculation); #endif handle_area()->oops_do(f); @@ -1426,7 +1426,7 @@ // ======= JavaThread ======== -#ifdef JVMCI +#if INCLUDE_JVMCI jlong* JavaThread::_jvmci_old_thread_counters; @@ -1451,7 +1451,7 @@ } } -#endif // JVMCI +#endif // A JavaThread is a normal Java thread @@ -1486,7 +1486,7 @@ _in_deopt_handler = 0; _doing_unsafe_access = false; _stack_guard_state = stack_guard_unused; -#ifdef JVMCI +#if INCLUDE_JVMCI _jvmci_alternate_call_target = NULL; _jvmci_implicit_exception_pc = NULL; if (JVMCICounterSize > 0) { @@ -1495,7 +1495,7 @@ } else { _jvmci_counters = NULL; } -#endif // JVMCI +#endif (void)const_cast<oop&>(_exception_oop = NULL); _exception_pc = 0; _exception_handler_pc = 0; @@ -1676,7 +1676,7 @@ if (_thread_profiler != NULL) delete _thread_profiler; if (_thread_stat != NULL) delete _thread_stat; -#ifdef JVMCI +#if INCLUDE_JVMCI if (JVMCICounterSize > 0) { if (jvmci_counters_include(this)) { for (int i = 0; i < JVMCICounterSize; i++) { @@ -1685,7 +1685,7 @@ } FREE_C_HEAP_ARRAY(jlong, _jvmci_counters, mtInternal); } -#endif // JVMCI +#endif } @@ -3395,7 +3395,7 @@ jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; -#ifdef JVMCI +#if INCLUDE_JVMCI OptionValuesTable* options = JVMCIRuntime::parse_arguments(); if (options == NULL) { return JNI_ERR; @@ -3456,14 +3456,14 @@ // Initialize global data structures and create system classes in heap vm_init_globals(); -#ifdef JVMCI +#if INCLUDE_JVMCI if (JVMCICounterSize > 0) { JavaThread::_jvmci_old_thread_counters = NEW_C_HEAP_ARRAY(jlong, JVMCICounterSize, mtInternal); memset(JavaThread::_jvmci_old_thread_counters, 0, sizeof(jlong) * JVMCICounterSize); } else { JavaThread::_jvmci_old_thread_counters = NULL; } -#endif // JVMCI +#endif // Attach the main thread to this os thread JavaThread* main_thread = new JavaThread(); @@ -3709,7 +3709,7 @@ Chunk::start_chunk_pool_cleaner_task(); } -#ifdef JVMCI +#if INCLUDE_JVMCI JVMCIRuntime::set_options(options, main_thread); delete options; #endif @@ -4133,11 +4133,11 @@ delete thread; -#ifdef JVMCI +#if INCLUDE_JVMCI if (JVMCICounterSize > 0) { FREE_C_HEAP_ARRAY(jlong, JavaThread::_jvmci_old_thread_counters, mtInternal); } -#endif // JVMCI +#endif // exit_globals() will delete tty exit_globals();
--- a/src/share/vm/runtime/thread.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/thread.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -916,7 +916,7 @@ private: -#ifdef JVMCI +#if INCLUDE_JVMCI address _jvmci_alternate_call_target; address _jvmci_implicit_exception_pc; // pc at which the most recent implicit exception occurred @@ -926,7 +926,7 @@ static jlong* _jvmci_old_thread_counters; static void collect_counters(typeArrayOop array); private: -#endif // JVMCI +#endif nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper @@ -1301,7 +1301,7 @@ MemRegion deferred_card_mark() const { return _deferred_card_mark; } void set_deferred_card_mark(MemRegion mr) { _deferred_card_mark = mr; } -#ifdef JVMCI +#if INCLUDE_JVMCI void set_jvmci_alternate_call_target(address a) { _jvmci_alternate_call_target = a; } void set_jvmci_implicit_exception_pc(address a) { _jvmci_implicit_exception_pc = a; } #endif @@ -1399,11 +1399,11 @@ static ByteSize thread_state_offset() { return byte_offset_of(JavaThread, _thread_state ); } static ByteSize saved_exception_pc_offset() { return byte_offset_of(JavaThread, _saved_exception_pc ); } static ByteSize osthread_offset() { return byte_offset_of(JavaThread, _osthread ); } -#ifdef JVMCI +#if INCLUDE_JVMCI static ByteSize jvmci_alternate_call_target_offset() { return byte_offset_of(JavaThread, _jvmci_alternate_call_target); } static ByteSize jvmci_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _jvmci_implicit_exception_pc); } static ByteSize jvmci_counters_offset() { return byte_offset_of(JavaThread, _jvmci_counters ); } -#endif // JVMCI +#endif static ByteSize exception_oop_offset() { return byte_offset_of(JavaThread, _exception_oop ); } static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); } static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }
--- a/src/share/vm/runtime/vmStructs.cpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Jul 24 02:11:18 2015 +0200 @@ -70,7 +70,7 @@ #include "oops/constMethod.hpp" #include "oops/constantPool.hpp" #include "oops/cpCache.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI #include "oops/fieldStreams.hpp" #endif #include "oops/instanceClassLoaderKlass.hpp" @@ -106,7 +106,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/hashtable.hpp" #include "utilities/macros.hpp" -#ifdef JVMCI +#if INCLUDE_JVMCI # include "jvmci/jvmciRuntime.hpp" # include "jvmci/vmStructs_jvmci.hpp" #endif @@ -3048,7 +3048,7 @@ GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY) -#ifdef JVMCI +#if INCLUDE_JVMCI VM_STRUCTS_JVMCI(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) #endif @@ -3097,7 +3097,7 @@ GENERATE_C2_VM_TYPE_ENTRY, GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY) -#ifdef JVMCI +#if INCLUDE_JVMCI VM_TYPES_JVMCI(GENERATE_VM_TYPE_ENTRY, GENERATE_TOPLEVEL_VM_TYPE_ENTRY) #endif @@ -3144,7 +3144,7 @@ GENERATE_C2_VM_INT_CONSTANT_ENTRY, GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) -#ifdef JVMCI +#if INCLUDE_JVMCI VM_INT_CONSTANTS_JVMCI(GENERATE_VM_INT_CONSTANT_ENTRY, GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) @@ -3496,7 +3496,7 @@ #endif -#ifdef JVMCI +#if INCLUDE_JVMCI // Emit intialization code for HotSpotVMConfig. It's placed here so // it can take advantage of the relaxed access checking enjoyed by // VMStructs.
--- a/src/share/vm/runtime/vmStructs.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/runtime/vmStructs.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -126,7 +126,7 @@ static void test(); #endif -#ifdef JVMCI +#if INCLUDE_JVMCI // The definition of this method is generated by // jdk.internal.jvmci.hotspotvmconfig.HotSpotVMConfigProcessor. static void initHotSpotVMConfig(oop config);
--- a/src/share/vm/utilities/exceptions.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/utilities/exceptions.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -61,7 +61,7 @@ friend class VMStructs; protected: -#ifdef JVMCI +#if INCLUDE_JVMCI int _pending_deoptimization; oop _pending_failed_speculation; bool _pending_monitorenter; @@ -85,7 +85,7 @@ bool has_pending_exception() const { return _pending_exception != NULL; } const char* exception_file() const { return _exception_file; } int exception_line() const { return _exception_line; } -#ifdef JVMCI +#if INCLUDE_JVMCI int pending_deoptimization() const { return _pending_deoptimization; } oop pending_failed_speculation() const { return _pending_failed_speculation; } bool has_pending_monitorenter() const { return _pending_monitorenter; } @@ -93,7 +93,7 @@ // Code generation support static ByteSize pending_exception_offset() { return byte_offset_of(ThreadShadow, _pending_exception); } -#ifdef JVMCI +#if INCLUDE_JVMCI static ByteSize pending_deoptimization_offset() { return byte_offset_of(ThreadShadow, _pending_deoptimization); } static ByteSize pending_monitorenter_offset() { return byte_offset_of(ThreadShadow, _pending_monitorenter); } static ByteSize pending_failed_speculation_offset() { return byte_offset_of(ThreadShadow, _pending_failed_speculation); } @@ -112,7 +112,7 @@ ThreadShadow() : _pending_exception(NULL), _exception_file(NULL), _exception_line(0) -#ifdef JVMCI +#if INCLUDE_JVMCI , _pending_monitorenter(false), _pending_deoptimization(-1), _pending_failed_speculation(NULL), _pending_transfer_to_interpreter(false) #endif {}
--- a/src/share/vm/utilities/macros.hpp Thu Jul 23 22:16:06 2015 +0200 +++ b/src/share/vm/utilities/macros.hpp Fri Jul 24 02:11:18 2015 +0200 @@ -164,6 +164,20 @@ #define INCLUDE_TRACE 1 #endif // INCLUDE_TRACE +#ifndef INCLUDE_JVMCI +#define INCLUDE_JVMCI 1 +#endif + +#if INCLUDE_JVMCI +#define JVMCI_ONLY(code) code +#define NOT_JVMCI(code) +#define IS_JVMCI_DEFINED true +#else +#define JVMCI_ONLY(code) +#define NOT_JVMCI(code) code +#define IS_JVMCI_DEFINED false +#endif // JVMCI + // COMPILER1 variant #ifdef COMPILER1 #if defined(COMPILER2) || defined(COMPILERJVMCI) @@ -191,20 +205,10 @@ #define NOT_COMPILERJVMCI(code) code #endif // COMPILERJVMCI -#if defined(COMPILERJVMCI) && !defined(JVMCI) -#error "COMPILERJVMCI needs JVMCI to be defined" +#if defined(COMPILERJVMCI) && !INCLUDE_JVMCI +#error "COMPILERJVMCI needs INCLUDE_JVMCI=1" #endif -#ifdef JVMCI -#define JVMCI_ONLY(code) code -#define NOT_JVMCI(code) -#define IS_JVMCI_DEFINED true -#else // JVMCI -#define JVMCI_ONLY(code) -#define NOT_JVMCI(code) code -#define IS_JVMCI_DEFINED false -#endif // JVMCI - #ifdef TIERED #define TIERED_ONLY(code) code #define NOT_TIERED(code)