}
/*
- * 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);
dvmResumeAllThreads(SUSPEND_FOR_SAMPLING);
- usleep(gDvm.methodTrace.samplingIntervalUs);
+ usleep(intervalUs);
}
return NULL;
}
* 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;
state->recordSize = TRACE_REC_SIZE_SINGLE_CLOCK;
}
- /* TODO: Control sampling through gui. */
- state->samplingEnabled = false;
- state->samplingIntervalUs = 1000;
+ state->samplingEnabled = samplingEnabled;
/*
* Output the header.
* 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;
}
void dvmMethodTraceStop()
{
MethodTraceState* state = &gDvm.methodTrace;
+ bool samplingEnabled = state->samplingEnabled;
u8 elapsed;
/*
dvmUnlockMutex(&state->startStopLock);
return;
} else {
- if (state->samplingEnabled) {
+ if (samplingEnabled) {
updateActiveProfilers(kSubModeSampleTrace, false);
} else {
updateActiveProfilers(kSubModeMethodTrace, false);
state->traceFile = NULL;
/* free and clear sampling traces held by all threads */
- if (state->samplingEnabled) {
+ if (samplingEnabled) {
freeThreadStackTraceSamples();
}
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");
}
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");
}
/*
- * 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];
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();
}
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",