diff options
author | Jeff Hao <jeffhao@google.com> | 2013-08-22 15:36:42 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2013-08-26 16:44:06 -0700 |
commit | 23009dca63c1699e28bfeaa8b45ca48fa0e86ace (patch) | |
tree | 33645ffca45249f4d8dc351dca17327c29613317 | |
parent | fb2451b516f8411756fe7b6f91b5534cf3ce8682 (diff) | |
download | android_art-23009dca63c1699e28bfeaa8b45ca48fa0e86ace.tar.gz android_art-23009dca63c1699e28bfeaa8b45ca48fa0e86ace.tar.bz2 android_art-23009dca63c1699e28bfeaa8b45ca48fa0e86ace.zip |
Add art support for sample profiling from traceview gui.
Change-Id: I6004bf143521b872084ca4aae873bea3524aa895
-rw-r--r-- | runtime/native/dalvik_system_VMDebug.cc | 12 | ||||
-rw-r--r-- | runtime/runtime.cc | 3 | ||||
-rw-r--r-- | runtime/trace.cc | 33 | ||||
-rw-r--r-- | runtime/trace.h | 16 |
4 files changed, 30 insertions, 34 deletions
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc index 2956c2c90a..ae45701a53 100644 --- a/runtime/native/dalvik_system_VMDebug.cc +++ b/runtime/native/dalvik_system_VMDebug.cc @@ -37,6 +37,7 @@ static jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) { 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"); return toStringArray(env, features); @@ -58,8 +59,9 @@ static void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) { Runtime::Current()->ResetStats(kinds); } -static void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags) { - Trace::Start("[DDMS]", -1, bufferSize, flags, true); +static void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags, + jboolean samplingEnabled, jint intervalUs) { + Trace::Start("[DDMS]", -1, bufferSize, flags, true, samplingEnabled, intervalUs); } static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, @@ -82,7 +84,7 @@ static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceF if (traceFilename.c_str() == NULL) { return; } - Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, false); + Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, false, false, 0); } static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, @@ -91,7 +93,7 @@ static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring java if (traceFilename.c_str() == NULL) { return; } - Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, false); + Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, false, false, 0); } static jboolean VMDebug_isMethodTracingActive(JNIEnv*, jclass) { @@ -323,7 +325,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(VMDebug, startAllocCounting, "()V"), NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"), NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"), - NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(II)V"), + NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(IIZI)V"), NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V"), NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;II)V"), NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"), diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 51a67c1bf4..5679d4ea83 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -925,7 +925,8 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { method_trace_file_size_ = options->method_trace_file_size_; if (options->method_trace_) { - Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, false); + Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, + false, false, 0); } VLOG(startup) << "Runtime::Init exiting"; diff --git a/runtime/trace.cc b/runtime/trace.cc index 4c092fd8b5..6d040e15dc 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -122,9 +122,6 @@ ProfilerClockSource Trace::default_clock_source_ = kProfilerClockSourceWall; #endif Trace* volatile Trace::the_trace_ = NULL; -// TODO: Add way to enable sampling and set interval through gui. -bool Trace::sampling_enabled_ = true; -uint32_t Trace::sampling_interval_us_ = 1000; pthread_t Trace::sampling_pthread_ = 0U; UniquePtr<std::vector<mirror::ArtMethod*> > Trace::temp_stack_trace_; @@ -301,11 +298,12 @@ void Trace::CompareAndUpdateStackTrace(Thread* thread, void* Trace::RunSamplingThread(void* arg) { Runtime* runtime = Runtime::Current(); + int interval_us = reinterpret_cast<int>(arg); CHECK(runtime->AttachCurrentThread("Sampling Profiler", true, runtime->GetSystemThreadGroup(), !runtime->IsCompiler())); while (true) { - usleep(sampling_interval_us_); + usleep(interval_us); ATRACE_BEGIN("Profile sampling"); Thread* self = Thread::Current(); Trace* the_trace; @@ -331,7 +329,7 @@ void* Trace::RunSamplingThread(void* arg) { } void Trace::Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, - bool direct_to_ddms) { + bool direct_to_ddms, bool sampling_enabled, int interval_us) { Thread* self = Thread::Current(); { MutexLock mu(self, *Locks::trace_lock_); @@ -367,16 +365,19 @@ void Trace::Start(const char* trace_filename, int trace_fd, int buffer_size, int if (the_trace_ != NULL) { LOG(ERROR) << "Trace already in progress, ignoring this request"; } else { - the_trace_ = new Trace(trace_file.release(), buffer_size, flags); + the_trace_ = new Trace(trace_file.release(), buffer_size, flags, sampling_enabled); // Enable count of allocs if specified in the flags. if ((flags && kTraceCountAllocs) != 0) { runtime->SetStatsEnabled(true); } - if (sampling_enabled_) { - CHECK_PTHREAD_CALL(pthread_create, (&sampling_pthread_, NULL, &RunSamplingThread, NULL), - "Sampling profiler thread"); + + + if (sampling_enabled) { + CHECK_PTHREAD_CALL(pthread_create, (&sampling_pthread_, NULL, &RunSamplingThread, + reinterpret_cast<void*>(interval_us)), + "Sampling profiler thread"); } else { runtime->GetInstrumentation()->AddListener(the_trace_, instrumentation::Instrumentation::kMethodEntered | @@ -407,7 +408,7 @@ void Trace::Stop() { if (the_trace != NULL) { the_trace->FinishTracing(); - if (sampling_enabled_) { + if (the_trace->sampling_enabled_) { MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); runtime->GetThreadList()->ForEach(ClearThreadStackTraceAndClockBase, NULL); } else { @@ -420,7 +421,7 @@ void Trace::Stop() { } runtime->GetThreadList()->ResumeAll(); - if (sampling_enabled_ && sampling_pthread != 0U) { + if (sampling_pthread != 0U) { CHECK_PTHREAD_CALL(pthread_join, (sampling_pthread, NULL), "sampling thread shutdown"); } } @@ -436,10 +437,10 @@ bool Trace::IsMethodTracingActive() { return the_trace_ != NULL; } -Trace::Trace(File* trace_file, int buffer_size, int flags) +Trace::Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled) : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), - clock_source_(default_clock_source_), buffer_size_(buffer_size), start_time_(MicroTime()), - cur_offset_(0), overflow_(false) { + sampling_enabled_(sampling_enabled), clock_source_(default_clock_source_), + buffer_size_(buffer_size), start_time_(MicroTime()), cur_offset_(0), overflow_(false) { // Set up the beginning of the trace. uint16_t trace_version = GetTraceVersion(clock_source_); memset(buf_.get(), 0, kTraceHeaderLength); @@ -456,10 +457,6 @@ Trace::Trace(File* trace_file, int buffer_size, int flags) cur_offset_ = kTraceHeaderLength; } -Trace::~Trace() { - CHECK_EQ(sampling_pthread_, static_cast<pthread_t>(0U)); -} - static void DumpBuf(uint8_t* buf, size_t buf_size, ProfilerClockSource clock_source) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uint8_t* ptr = buf + kTraceHeaderLength; diff --git a/runtime/trace.h b/runtime/trace.h index 6fc3790a23..06cb6a6d5b 100644 --- a/runtime/trace.h +++ b/runtime/trace.h @@ -51,7 +51,7 @@ class Trace : public instrumentation::InstrumentationListener { static void SetDefaultClockSource(ProfilerClockSource clock_source); static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, - bool direct_to_ddms) + bool direct_to_ddms, bool sampling_enabled, int interval_us) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_, Locks::thread_suspend_count_lock_, @@ -88,11 +88,10 @@ class Trace : public instrumentation::InstrumentationListener { // Clear and store an old stack trace for later use. static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); - ~Trace(); - private: - explicit Trace(File* trace_file, int buffer_size, int flags); + explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); + // The sampling interval in microseconds is passed as an argument. static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -115,12 +114,6 @@ class Trace : public instrumentation::InstrumentationListener { // The default profiler clock source. static ProfilerClockSource default_clock_source_; - // True if traceview should sample instead of instrumenting method entry/exit. - static bool sampling_enabled_; - - // Sampling interval in microseconds. - static uint32_t sampling_interval_us_; - // Sampling thread, non-zero when sampling. static pthread_t sampling_pthread_; @@ -136,6 +129,9 @@ class Trace : public instrumentation::InstrumentationListener { // Flags enabling extra tracing of things such as alloc counts. const int flags_; + // True if traceview should sample instead of instrumenting method entry/exit. + const bool sampling_enabled_; + const ProfilerClockSource clock_source_; // Size of buf_. |