Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17510863 authored by Brian Carlstrom's avatar Brian Carlstrom
Browse files

New Java-based SamplingProfiler

Summary:
- libcore: new Java based SamplingProfiler
- dalvik: remove old SamplingProfiler native bits
- frameworks/base: New placeholder SamplingProfilerIntegration
- vendor/google: remove old profiler snapshot parsing code

Details:

libcore

   A new 100% Java SamplingProfiler. While it has more overhead that
   the old native one, the new one can actually collect more than the
   current PC and frame pointer, so you can get useful context of
   where your app is spending time. It currently provides ASCII hprof
   format output for use with tools like PerfAnal
	dalvik/src/main/java/dalvik/system/SamplingProfiler.java

    Unit test for the new SamplingProfiler
	dalvik/src/test/java/dalvik/system/SamplingProfilerTest.java

    Add core-tests-dalvik
	JavaLibrary.mk

dalvik

    Removing native code that supported the old SamplingProfiler
	vm/Dvm.mk
	vm/native/InternalNative.c
	vm/native/dalvik_system_SamplingProfiler.c

frameworks/base

  Placeholder SamplingProfilerIntegration. Later plans include
  generating EventStackTrace protobufs.

    New SamplingProfiler does not have a global instance, so
    SamplingProfilerIntegration provides one in INSTANCE. Old binary
    snapshot format is temporily replaced with ASCII hprof data.
	core/java/com/android/internal/os/SamplingProfilerIntegration.java

    Simplified interface for zygote profile snapshotting
	core/java/com/android/internal/os/ZygoteInit.java

    Current SamplingProfilerIntegration does not track event loop
    explicitly, but hprof information does include thread information.
	core/java/android/app/ActivityThread.java

vendor/google

    Removing code for parsing old SamplingProfiler snapshot format
	tools/samplingprofiler/Android.mk
	tools/samplingprofiler/NOTICE
	tools/samplingprofiler/profiler.iml
	tools/samplingprofiler/profiler.ipr
	tools/samplingprofiler/pull-snapshots.sh
	tools/samplingprofiler/sorttable.js
	tools/samplingprofiler/src/com/android/profiler/PrintHtml.java
parent 73ef5d4e
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -837,10 +837,6 @@ public final class ActivityThread {
    }

    private final class H extends Handler {
        private H() {
            SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
        }

        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
+49 −33
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package com.android.internal.os;

import dalvik.system.SamplingProfiler;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@@ -48,6 +50,8 @@ public class SamplingProfilerIntegration {
        }
    }

    private static SamplingProfiler INSTANCE;

    /**
     * Is profiling enabled?
     */
@@ -59,8 +63,13 @@ public class SamplingProfilerIntegration {
     * Starts the profiler if profiling is enabled.
     */
    public static void start() {
        if (!enabled) return;
        SamplingProfiler.getInstance().start(10);
        if (!enabled) {
            return;
        }
        ThreadGroup group = Thread.currentThread().getThreadGroup();
        SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group);
        INSTANCE = new SamplingProfiler(4, threadSet);
        INSTANCE.start(10);
    }

    /** Whether or not we've created the snapshots dir. */
@@ -73,7 +82,9 @@ public class SamplingProfilerIntegration {
     * Writes a snapshot to the SD card if profiling is enabled.
     */
    public static void writeSnapshot(final String name) {
        if (!enabled) return;
        if (!enabled) {
            return;
        }

        /*
         * If we're already writing a snapshot, don't bother enqueing another
@@ -109,18 +120,22 @@ public class SamplingProfilerIntegration {
     * Writes the zygote's snapshot to internal storage if profiling is enabled.
     */
    public static void writeZygoteSnapshot() {
        if (!enabled) return;
        if (!enabled) {
            return;
        }

        String dir = "/data/zygote/snapshots";
        new File(dir).mkdirs();
        writeSnapshot(dir, "zygote");
        INSTANCE.shutdown();
        INSTANCE = null;
    }

    private static void writeSnapshot(String dir, String name) {
        byte[] snapshot = SamplingProfiler.getInstance().snapshot();
        if (snapshot == null) {
        if (!enabled) {
            return;
        }
        INSTANCE.stop();

        /*
         * We use the current time as a unique ID. We can't use a counter
@@ -128,15 +143,15 @@ public class SamplingProfilerIntegration {
         * we capture two snapshots in rapid succession.
         */
        long start = System.currentTimeMillis();
        String path = dir + "/" + name.replace(':', '.') + "-" +
        String path = dir + "/" + name.replace(':', '.') + "-"
                + System.currentTimeMillis() + ".snapshot";
        try {

        // Try to open the file a few times. The SD card may not be mounted.
            FileOutputStream out;
        PrintStream out;
        int count = 0;
        while (true) {
            try {
                    out = new FileOutputStream(path);
                out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path)));
                break;
            } catch (FileNotFoundException e) {
                if (++count > 3) {
@@ -152,15 +167,16 @@ public class SamplingProfilerIntegration {
        }

        try {
                out.write(snapshot);
            INSTANCE.writeHprofData(out);
        } finally {
            out.close();
        }
        if (out.checkError()) {
            Log.e(TAG, "Error writing snapshot.");
        } else {
            long elapsed = System.currentTimeMillis() - start;
            Log.i(TAG, "Wrote snapshot for " + name
                  + " in " + elapsed + "ms.");
        } catch (IOException e) {
            Log.e(TAG, "Error writing snapshot.", e);
        }
    }
}
+2 −6
Original line number Diff line number Diff line
@@ -575,12 +575,8 @@ public class ZygoteInit {
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            if (SamplingProfilerIntegration.isEnabled()) {
                SamplingProfiler sp = SamplingProfiler.getInstance();
                sp.pause();
            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();
                sp.shutDown();
            }

            // Do an initial gc to clean up after startup
            gc();