Search in sources :

Example 1 with GlobalMetrics

use of org.graalvm.compiler.debug.GlobalMetrics in project graal by oracle.

the class CompileTheWorld method compile.

/**
 * Compiles all methods in all classes in a given class path.
 *
 * @param classPath class path denoting classes to compile
 * @throws IOException
 */
@SuppressWarnings("try")
private void compile(String classPath, LibGraalParams libgraal) throws IOException {
    final String[] entries = classPath.split(File.pathSeparator);
    Map<Thread, StackTraceElement[]> initialThreads = Thread.getAllStackTraces();
    if (libgraal == null) {
        try {
            // compile dummy method to get compiler initialized outside of the
            // config debug override.
            HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod(CompileTheWorld.class.getDeclaredMethod("dummy"));
            int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
            boolean useProfilingInfo = false;
            boolean installAsDefault = false;
            CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), useProfilingInfo, installAsDefault);
            task.runCompilation(compilerOptions);
        } catch (NoSuchMethodException | SecurityException e1) {
            printStackTrace(e1);
        }
    }
    int startAtClass = startAt;
    int stopAtClass = stopAt;
    if (startAtClass >= stopAtClass) {
        throw new IllegalArgumentException(String.format("StartAt (%d) must be less than StopAt (%d)", startAtClass, stopAtClass));
    }
    int startAtCompile = Options.StartAtCompile.getValue(harnessOptions);
    int stopAtCompile = Options.StopAtCompile.getValue(harnessOptions);
    if (startAtCompile >= stopAtCompile) {
        throw new IllegalArgumentException(String.format("StartAtCompile (%d) must be less than StopAtCompile (%d)", startAtCompile, stopAtCompile));
    }
    int classStep = 1;
    if (maxClasses != Integer.MAX_VALUE) {
        int totalClassFileCount = 0;
        for (String entry : entries) {
            try (ClassPathEntry cpe = openClassPathEntry(entry)) {
                if (cpe != null) {
                    totalClassFileCount += cpe.getClassNames().size();
                }
            }
        }
        int lastClassFile = totalClassFileCount - 1;
        startAtClass = Math.min(startAt, lastClassFile);
        stopAtClass = Math.min(stopAt, lastClassFile);
        int range = stopAtClass - startAtClass + 1;
        if (maxClasses < range) {
            classStep = range / maxClasses;
        }
    }
    TTY.println("CompileTheWorld : Gathering compilations ...");
    Map<HotSpotResolvedJavaMethod, Integer> toBeCompiled = gatherCompilations(entries, startAtClass, stopAtClass, classStep);
    /*
         * 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.MultiThreaded.getValue(harnessOptions)) {
        threadCount = Options.Threads.getValue(harnessOptions);
        if (threadCount == 0) {
            threadCount = Runtime.getRuntime().availableProcessors();
        }
        TTY.println("CompileTheWorld : Using %d threads", threadCount);
    }
    threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new CTWThreadFactory(libgraal));
    TTY.println("CompileTheWorld : Starting compilations ...");
    long start = System.nanoTime();
    int compilationNum = 0;
    int allCompiles = Math.min(toBeCompiled.size(), stopAtCompile) - Math.max(0, startAtCompile);
    int maxCompiles = Options.MaxCompiles.getValue(harnessOptions);
    float selector = Math.max(0, startAtCompile);
    float selectorStep = maxCompiles < allCompiles ? (float) allCompiles / maxCompiles : 1.0f;
    int repeat = Options.Repeat.getValue(harnessOptions);
    long taskCount = 0;
    for (Map.Entry<HotSpotResolvedJavaMethod, Integer> e : toBeCompiled.entrySet()) {
        if (compilationNum >= startAtCompile && compilationNum < stopAtCompile) {
            if (Math.round(selector) == compilationNum) {
                for (int i = 0; i < repeat; i++) {
                    taskCount++;
                    threadPool.submit(new Runnable() {

                        @Override
                        public void run() {
                            compileMethod(e.getKey(), e.getValue(), libgraal);
                        }
                    });
                }
                selector += selectorStep;
            }
        }
        compilationNum++;
    }
    int wakeups = 0;
    long lastCompletedTaskCount = 0;
    int statsInterval = Options.StatsInterval.getValue(harnessOptions);
    long completedTaskCount;
    do {
        completedTaskCount = threadPool.getCompletedTaskCount();
        if (completedTaskCount != 0 && (wakeups % statsInterval == 0 || completedTaskCount == taskCount)) {
            long compilationsInInterval = completedTaskCount - lastCompletedTaskCount;
            double rate = (double) compilationsInInterval / statsInterval;
            long percent = completedTaskCount * 100 / taskCount;
            TTY.println("CompileTheWorld : [%2d%%, %.1f compiles/s] %d of %d compilations completed, %d in last interval", percent, rate, completedTaskCount, taskCount, compilationsInInterval);
            if (libgraal != null) {
                armPrintMetrics();
            }
            lastCompletedTaskCount = completedTaskCount;
        }
        try {
            threadPool.awaitTermination(1, TimeUnit.SECONDS);
            wakeups++;
        } catch (InterruptedException e) {
        }
    } while (completedTaskCount != taskCount);
    threadPool.shutdown();
    threadPool = null;
    long elapsedTime = System.nanoTime() - start;
    println();
    int compiledClasses = classFileCounter > startAtClass ? classFileCounter - startAtClass : 0;
    int compiledBytecodes = compileTimes.keySet().stream().collect(Collectors.summingInt(ResolvedJavaMethod::getCodeSize));
    int compiledMethods = compileTimes.size();
    long elapsedTimeSeconds = nanoToMillis(compileTime.get()) / 1_000;
    double rateInMethods = (double) compiledMethods / elapsedTimeSeconds;
    double rateInBytecodes = (double) compiledBytecodes / elapsedTimeSeconds;
    TTY.println("CompileTheWorld : ======================== Done ======================");
    TTY.println("CompileTheWorld :         Compiled classes: %,d", compiledClasses);
    TTY.println("CompileTheWorld :         Compiled methods: %,d [%,d bytecodes]", compiledMethods, compiledBytecodes);
    TTY.println("CompileTheWorld :             Elapsed time: %,d ms", nanoToMillis(elapsedTime));
    TTY.println("CompileTheWorld :             Compile time: %,d ms", nanoToMillis(compileTime.get()));
    TTY.println("CompileTheWorld :  Compilation rate/thread: %,.1f methods/sec, %,.0f bytecodes/sec", rateInMethods, rateInBytecodes);
    TTY.println("CompileTheWorld : HotSpot heap memory used: %,.3f MB", (double) memoryUsed.get() / 1_000_000);
    TTY.println("CompileTheWorld :     Huge methods skipped: %,d", hugeMethods.size());
    int limit = Options.MetricsReportLimit.getValue(harnessOptions);
    if (limit > 0) {
        TTY.println("Longest compile times:");
        compileTimes.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())).limit(limit).forEach(e -> {
            long time = nanoToMillis(e.getValue());
            ResolvedJavaMethod method = e.getKey();
            TTY.println("  %,10d ms   %s [bytecodes: %d]", time, method.format("%H.%n(%p)"), method.getCodeSize());
        });
        TTY.println("Largest methods skipped due to bytecode size exceeding HugeMethodLimit (%d):", getHugeMethodLimit(compiler.getGraalRuntime().getVMConfig()));
        hugeMethods.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())).limit(limit).forEach(e -> {
            ResolvedJavaMethod method = e.getKey();
            TTY.println("  %,10d      %s", e.getValue(), method.format("%H.%n(%p)"), method.getCodeSize());
        });
    }
    GlobalMetrics metricValues = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMetricValues();
    EconomicMap<MetricKey, Long> map = metricValues.asKeyValueMap();
    Long compiledAndInstalledBytecodes = map.get(CompiledAndInstalledBytecodes);
    Long compilationTime = map.get(CompilationTime);
    if (compiledAndInstalledBytecodes != null && compilationTime != null) {
        TTY.println("CompileTheWorld : Aggregate compile speed %d bytecodes per second (%d / %d)", (int) (compiledAndInstalledBytecodes / (compilationTime / 1000000000.0)), compiledAndInstalledBytecodes, compilationTime);
    }
    metricValues.print(compilerOptions);
    metricValues.clear();
    // Apart from the main thread, there should be only be daemon threads
    // alive now. If not, then a class initializer has probably started
    // a thread that could cause a deadlock while trying to exit the VM.
    // One known example of this is sun.tools.jconsole.OutputViewer which
    // spawns threads to redirect sysout and syserr. To help debug such
    // scenarios, the stacks of potentially problematic threads are dumped.
    Map<Thread, StackTraceElement[]> suspiciousThreads = new HashMap<>();
    for (Map.Entry<Thread, StackTraceElement[]> e : Thread.getAllStackTraces().entrySet()) {
        Thread thread = e.getKey();
        if (thread != Thread.currentThread() && !initialThreads.containsKey(thread) && !thread.isDaemon() && thread.isAlive()) {
            suspiciousThreads.put(thread, e.getValue());
        }
    }
    if (!suspiciousThreads.isEmpty()) {
        TTY.println("--- Non-daemon threads started during CTW ---");
        for (Map.Entry<Thread, StackTraceElement[]> e : suspiciousThreads.entrySet()) {
            Thread thread = e.getKey();
            if (thread.isAlive()) {
                TTY.println(thread.toString() + " " + thread.getState());
                for (StackTraceElement ste : e.getValue()) {
                    TTY.println("\tat " + ste);
                }
            }
        }
        TTY.println("---------------------------------------------");
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) MetricKey(org.graalvm.compiler.debug.MetricKey) HotSpotResolvedJavaMethod(jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod) HotSpotCompilationRequest(jdk.vm.ci.hotspot.HotSpotCompilationRequest) GlobalMetrics(org.graalvm.compiler.debug.GlobalMetrics) Print(org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Print) CompilationTask(org.graalvm.compiler.hotspot.CompilationTask) AtomicLong(java.util.concurrent.atomic.AtomicLong) HotSpotGraalRuntime(org.graalvm.compiler.hotspot.HotSpotGraalRuntime) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) EconomicMap(org.graalvm.collections.EconomicMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) HotSpotResolvedJavaMethod(jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 2 with GlobalMetrics

use of org.graalvm.compiler.debug.GlobalMetrics in project graal by oracle.

the class LibGraalEntryPoints method compileMethod.

/**
 * The implementation of
 * {@code org.graalvm.compiler.hotspot.test.CompileTheWorld.compileMethodInLibgraal()}.
 *
 * @param methodHandle the method to be compiled. This is a handle to a
 *            {@link HotSpotResolvedJavaMethod} in HotSpot's heap. A value of 0L can be passed
 *            to use this method for the side effect of initializing a
 *            {@link HotSpotGraalCompiler} instance without doing any compilation.
 * @param useProfilingInfo specifies if profiling info should be used during the compilation
 * @param installAsDefault specifies if the compiled code should be installed for the
 *            {@code Method*} associated with {@code methodHandle}
 * @param printMetrics specifies if global metrics should be printed and reset
 * @param optionsAddress native byte buffer storing a serialized {@link OptionValues} object
 * @param optionsSize the number of bytes in the buffer
 * @param optionsHash hash code of bytes in the buffer (computed with
 *            {@link Arrays#hashCode(byte[])})
 * @param stackTraceAddress a native buffer in which a serialized stack trace can be returned.
 *            The caller will only read from this buffer if this method returns 0. A returned
 *            serialized stack trace is returned in this buffer with the following format:
 *
 *            <pre>
 *            struct {
 *                int   length;
 *                byte  data[length]; // Bytes from a stack trace printed to a ByteArrayOutputStream.
 *            }
 *            </pre>
 *
 *            where {@code length} truncated to {@code stackTraceCapacity - 4} if necessary
 *
 * @param stackTraceCapacity the size of the stack trace buffer
 * @return a handle to a {@link InstalledCode} in HotSpot's heap or 0 if compilation failed
 */
@SuppressWarnings({ "unused", "try" })
@CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_test_CompileTheWorld_compileMethodInLibgraal", include = LibGraalFeature.IsEnabled.class)
private static long compileMethod(PointerBase jniEnv, PointerBase jclass, @CEntryPoint.IsolateThreadContext long isolateThread, long methodHandle, boolean useProfilingInfo, boolean installAsDefault, boolean printMetrics, long optionsAddress, int optionsSize, int optionsHash, long stackTraceAddress, int stackTraceCapacity) {
    try {
        HotSpotJVMCIRuntime runtime = runtime();
        HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
        if (methodHandle == 0L) {
            return 0L;
        }
        HotSpotResolvedJavaMethod method = LibGraal.unhand(HotSpotResolvedJavaMethod.class, methodHandle);
        int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
        HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L);
        try (CompilationContext scope = HotSpotGraalServices.openLocalCompilationContext(request)) {
            OptionValues options = decodeOptions(optionsAddress, optionsSize, optionsHash);
            CompilationTask task = new CompilationTask(runtime, compiler, request, useProfilingInfo, installAsDefault);
            task.runCompilation(options);
            HotSpotInstalledCode installedCode = task.getInstalledCode();
            if (printMetrics) {
                GlobalMetrics metricValues = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMetricValues();
                metricValues.print(options);
                metricValues.clear();
            }
            return LibGraal.translate(installedCode);
        }
    } catch (Throwable t) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        t.printStackTrace(new PrintStream(baos));
        byte[] stackTrace = baos.toByteArray();
        int length = Math.min(stackTraceCapacity - Integer.BYTES, stackTrace.length);
        UNSAFE.putInt(stackTraceAddress, length);
        UNSAFE.copyMemory(stackTrace, ARRAY_BYTE_BASE_OFFSET, null, stackTraceAddress + Integer.BYTES, length);
        return 0L;
    } finally {
        /*
             * libgraal doesn't use a dedicated reference handler thread, so we trigger the
             * reference handling manually when a compilation finishes.
             */
        Heap.getHeap().doReferenceHandling();
    }
}
Also used : HotSpotGraalCompiler(org.graalvm.compiler.hotspot.HotSpotGraalCompiler) PrintStream(java.io.PrintStream) HotSpotResolvedJavaMethod(jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod) OptionValues(org.graalvm.compiler.options.OptionValues) HotSpotJVMCIRuntime(jdk.vm.ci.hotspot.HotSpotJVMCIRuntime) ByteArrayOutputStream(java.io.ByteArrayOutputStream) HotSpotCompilationRequest(jdk.vm.ci.hotspot.HotSpotCompilationRequest) GlobalMetrics(org.graalvm.compiler.debug.GlobalMetrics) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) CompilationTask(org.graalvm.compiler.hotspot.CompilationTask) CompilationContext(org.graalvm.compiler.hotspot.CompilationContext) HotSpotGraalRuntime(org.graalvm.compiler.hotspot.HotSpotGraalRuntime) HotSpotInstalledCode(jdk.vm.ci.hotspot.HotSpotInstalledCode) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint)

Aggregations

HotSpotCompilationRequest (jdk.vm.ci.hotspot.HotSpotCompilationRequest)2 HotSpotResolvedJavaMethod (jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod)2 GlobalMetrics (org.graalvm.compiler.debug.GlobalMetrics)2 CompilationTask (org.graalvm.compiler.hotspot.CompilationTask)2 HotSpotGraalRuntime (org.graalvm.compiler.hotspot.HotSpotGraalRuntime)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 PrintStream (java.io.PrintStream)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 HotSpotInstalledCode (jdk.vm.ci.hotspot.HotSpotInstalledCode)1 HotSpotJVMCIRuntime (jdk.vm.ci.hotspot.HotSpotJVMCIRuntime)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 EconomicMap (org.graalvm.collections.EconomicMap)1 Print (org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Print)1 MetricKey (org.graalvm.compiler.debug.MetricKey)1