OSDN Git Service

Add dalvik support for sample profiling from traceview gui.
authorJeff Hao <jeffhao@google.com>
Tue, 27 Aug 2013 20:33:08 +0000 (13:33 -0700)
committerBrian Carlstrom <bdc@google.com>
Thu, 29 Aug 2013 05:44:01 +0000 (22:44 -0700)
(cherry picked from commit 86bb14a3e4d7ef3b8b4240bbc2a8b989a1b8c7c0)

Change-Id: Ifece45f6a6644c20b6681a58dd3eae3534ad47e4

vm/Profile.cpp
vm/Profile.h
vm/native/dalvik_system_VMDebug.cpp

index 8492cd5..08e1463 100644 (file)
@@ -276,10 +276,12 @@ static void getSample(Thread* thread)
 }
 
 /*
- * Entry point for sampling thread.
+ * Entry point for sampling thread. The sampling interval in microseconds is
+ * passed in as an argument.
  */
 static void* runSamplingThread(void* arg)
 {
+    int intervalUs = (int) arg;
     while (gDvm.methodTrace.traceEnabled) {
         dvmSuspendAllThreads(SUSPEND_FOR_SAMPLING);
 
@@ -291,7 +293,7 @@ static void* runSamplingThread(void* arg)
 
         dvmResumeAllThreads(SUSPEND_FOR_SAMPLING);
 
-        usleep(gDvm.methodTrace.samplingIntervalUs);
+        usleep(intervalUs);
     }
     return NULL;
 }
@@ -500,7 +502,7 @@ static void dumpMethodList(FILE* fp)
  * On failure, we throw an exception and return.
  */
 void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
-    int flags, bool directToDdms)
+    int flags, bool directToDdms, bool samplingEnabled, int intervalUs)
 {
     MethodTraceState* state = &gDvm.methodTrace;
 
@@ -569,9 +571,7 @@ void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
         state->recordSize = TRACE_REC_SIZE_SINGLE_CLOCK;
     }
 
-    /* TODO: Control sampling through gui. */
-    state->samplingEnabled = false;
-    state->samplingIntervalUs = 1000;
+    state->samplingEnabled = samplingEnabled;
 
     /*
      * Output the header.
@@ -597,11 +597,11 @@ void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
      * following to take a Thread* argument, and set the appropriate
      * interpBreak flags only on the target thread.
      */
-    if (state->samplingEnabled) {
+    if (samplingEnabled) {
         updateActiveProfilers(kSubModeSampleTrace, true);
         /* Start the sampling thread. */
         if (!dvmCreateInternalThread(&state->samplingThreadHandle,
-                "Sampling Thread", &runSamplingThread, NULL)) {
+                "Sampling Thread", &runSamplingThread, (void*) intervalUs)) {
             dvmThrowInternalError("failed to create sampling thread");
             goto fail;
         }
@@ -706,6 +706,7 @@ bool dvmIsMethodTraceActive()
 void dvmMethodTraceStop()
 {
     MethodTraceState* state = &gDvm.methodTrace;
+    bool samplingEnabled = state->samplingEnabled;
     u8 elapsed;
 
     /*
@@ -720,7 +721,7 @@ void dvmMethodTraceStop()
         dvmUnlockMutex(&state->startStopLock);
         return;
     } else {
-        if (state->samplingEnabled) {
+        if (samplingEnabled) {
             updateActiveProfilers(kSubModeSampleTrace, false);
         } else {
             updateActiveProfilers(kSubModeMethodTrace, false);
@@ -879,7 +880,7 @@ void dvmMethodTraceStop()
     state->traceFile = NULL;
 
     /* free and clear sampling traces held by all threads */
-    if (state->samplingEnabled) {
+    if (samplingEnabled) {
         freeThreadStackTraceSamples();
     }
 
@@ -888,7 +889,7 @@ void dvmMethodTraceStop()
     dvmUnlockMutex(&state->startStopLock);
 
     /* make sure the sampling thread has stopped */
-    if (state->samplingEnabled &&
+    if (samplingEnabled &&
         pthread_join(state->samplingThreadHandle, NULL) != 0) {
         ALOGW("Sampling thread join failed");
     }
index 0ec8705..6a2c4be 100644 (file)
@@ -54,7 +54,6 @@ struct MethodTraceState {
     size_t  recordSize;
 
     bool    samplingEnabled;
-    int     samplingIntervalUs;
     pthread_t       samplingThreadHandle;
 };
 
@@ -87,7 +86,7 @@ struct AllocProfState {
  * Start/stop method tracing.
  */
 void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
-        int flags, bool directToDdms);
+        int flags, bool directToDdms, bool samplingEnabled, int intervalUs);
 bool dvmIsMethodTraceActive(void);
 void dvmMethodTraceStop(void);
 
index d03f6f4..8ba304a 100644 (file)
@@ -56,6 +56,7 @@ static void Dalvik_dalvik_system_VMDebug_getVmFeatureList(const u4* args, JValue
     std::vector<std::string> features;
     features.push_back("method-trace-profiling");
     features.push_back("method-trace-profiling-streaming");
+    features.push_back("method-sample-profiling");
     features.push_back("hprof-heap-dump");
     features.push_back("hprof-heap-dump-streaming");
 
@@ -224,16 +225,30 @@ static void Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4* args,
 }
 
 /*
- * static void startMethodTracingNative(String traceFileName,
- *     FileDescriptor fd, int bufferSize, int flags)
+ * static void startMethodTracingDdmsImpl(int bufferSize, int flags,
+ *     boolean samplingEnabled, int intervalUs)
  *
- * Start method trace profiling.
+ * Start method trace profiling, sending results directly to DDMS.
+ */
+static void Dalvik_dalvik_system_VMDebug_startMethodTracingDdmsImpl(const u4* args,
+    JValue* pResult)
+{
+    int bufferSize = args[0];
+    int flags = args[1];
+    bool samplingEnabled = args[2];
+    int intervalUs = args[3];
+    dvmMethodTraceStart("[DDMS]", -1, bufferSize, flags, true, samplingEnabled,
+        intervalUs);
+    RETURN_VOID();
+}
+
+/*
+ * static void startMethodTracingFd(String traceFileName, FileDescriptor fd,
+ *     int bufferSize, int flags)
  *
- * If both "traceFileName" and "fd" are null, the result will be sent
- * directly to DDMS.  (The non-DDMS versions of the calls are expected
- * to enforce non-NULL filenames.)
+ * Start method trace profiling, sending results to a file descriptor.
  */
-static void Dalvik_dalvik_system_VMDebug_startMethodTracingNative(const u4* args,
+static void Dalvik_dalvik_system_VMDebug_startMethodTracingFd(const u4* args,
     JValue* pResult)
 {
     StringObject* traceFileStr = (StringObject*) args[0];
@@ -241,36 +256,46 @@ static void Dalvik_dalvik_system_VMDebug_startMethodTracingNative(const u4* args
     int bufferSize = args[2];
     int flags = args[3];
 
-    if (bufferSize == 0) {
-        // Default to 8MB per the documentation.
-        bufferSize = 8 * 1024 * 1024;
+    int origFd = getFileDescriptor(traceFd);
+    if (origFd < 0)
+        RETURN_VOID();
+
+    int fd = dup(origFd);
+    if (fd < 0) {
+        dvmThrowExceptionFmt(gDvm.exRuntimeException,
+            "dup(%d) failed: %s", origFd, strerror(errno));
+        RETURN_VOID();
     }
 
-    if (bufferSize < 1024) {
-        dvmThrowIllegalArgumentException(NULL);
+    char* traceFileName = dvmCreateCstrFromString(traceFileStr);
+    if (traceFileName == NULL) {
         RETURN_VOID();
     }
 
-    char* traceFileName = NULL;
-    if (traceFileStr != NULL)
-        traceFileName = dvmCreateCstrFromString(traceFileStr);
+    dvmMethodTraceStart(traceFileName, fd, bufferSize, flags, false, false, 0);
+    free(traceFileName);
+    RETURN_VOID();
+}
 
-    int fd = -1;
-    if (traceFd != NULL) {
-        int origFd = getFileDescriptor(traceFd);
-        if (origFd < 0)
-            RETURN_VOID();
+/*
+ * static void startMethodTracingFilename(String traceFileName, int bufferSize,
+ *     int flags)
+ *
+ * Start method trace profiling, sending results to a file.
+ */
+static void Dalvik_dalvik_system_VMDebug_startMethodTracingFilename(const u4* args,
+    JValue* pResult)
+{
+    StringObject* traceFileStr = (StringObject*) args[0];
+    int bufferSize = args[1];
+    int flags = args[2];
 
-        fd = dup(origFd);
-        if (fd < 0) {
-            dvmThrowExceptionFmt(gDvm.exRuntimeException,
-                "dup(%d) failed: %s", origFd, strerror(errno));
-            RETURN_VOID();
-        }
+    char* traceFileName = dvmCreateCstrFromString(traceFileStr);
+    if (traceFileName == NULL) {
+        RETURN_VOID();
     }
 
-    dvmMethodTraceStart(traceFileName != NULL ? traceFileName : "[DDMS]",
-        fd, bufferSize, flags, (traceFileName == NULL && fd == -1));
+    dvmMethodTraceStart(traceFileName, -1, bufferSize, flags, false, false, 0);
     free(traceFileName);
     RETURN_VOID();
 }
@@ -796,8 +821,12 @@ const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
         Dalvik_dalvik_system_VMDebug_startAllocCounting },
     { "stopAllocCounting",          "()V",
         Dalvik_dalvik_system_VMDebug_stopAllocCounting },
-    { "startMethodTracingNative",   "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V",
-        Dalvik_dalvik_system_VMDebug_startMethodTracingNative },
+    { "startMethodTracingDdmsImpl", "(IIZI)V",
+        Dalvik_dalvik_system_VMDebug_startMethodTracingDdmsImpl },
+    { "startMethodTracingFd",       "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V",
+        Dalvik_dalvik_system_VMDebug_startMethodTracingFd },
+    { "startMethodTracingFilename", "(Ljava/lang/String;II)V",
+        Dalvik_dalvik_system_VMDebug_startMethodTracingFilename },
     { "isMethodTracingActive",      "()Z",
         Dalvik_dalvik_system_VMDebug_isMethodTracingActive },
     { "stopMethodTracing",          "()V",