diff options
| author | 2012-05-22 17:37:06 -0700 | |
|---|---|---|
| committer | 2012-05-24 19:31:12 -0700 | |
| commit | e119a3623ffbd55ff856d4eaac4dc4ef0c90a089 (patch) | |
| tree | 142ce634272fc3e2e7d8b44c564fb3d72a01a33e | |
| parent | bf1b4574dc681d49696571c59033e8c63583a029 (diff) | |
Fix the TODOs in the traceview support.
(cherry picked from commit cfbe73d02a024800813f8f0fc4f6a4b4532195f3)
Change-Id: Ie9ee2701df665d92c544c2ac3b4eaf7209a881a5
| -rw-r--r-- | src/runtime.cc | 6 | ||||
| -rw-r--r-- | src/trace.cc | 89 | ||||
| -rw-r--r-- | src/trace.h | 19 |
3 files changed, 91 insertions, 23 deletions
diff --git a/src/runtime.cc b/src/runtime.cc index c4527712a3..e03305973d 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -465,6 +465,12 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:")); } else if (StartsWith(option, "-Xmethod-trace-file-size:")) { parsed->method_trace_file_size_ = ParseIntegerOrDie(option); + } else if (option == "-Xprofile:threadcpuclock") { + Trace::SetDefaultClockSource(kProfilerClockSourceThreadCpu); + } else if (option == "-Xprofile:wallclock") { + Trace::SetDefaultClockSource(kProfilerClockSourceWall); + } else if (option == "-Xprofile:dualclock") { + Trace::SetDefaultClockSource(kProfilerClockSourceDual); } else { if (!ignore_unrecognized) { // TODO: print usage via vfprintf diff --git a/src/trace.cc b/src/trace.cc index 7b7a767aef..aa6c523dd0 100644 --- a/src/trace.cc +++ b/src/trace.cc @@ -32,6 +32,40 @@ namespace art { +// File format: +// header +// record 0 +// record 1 +// ... +// +// Header format: +// u4 magic ('SLOW') +// u2 version +// u2 offset to data +// u8 start date/time in usec +// u2 record size in bytes (version >= 2 only) +// ... padding to 32 bytes +// +// Record format v1: +// u1 thread ID +// u4 method ID | method action +// u4 time delta since start, in usec +// +// Record format v2: +// u2 thread ID +// u4 method ID | method action +// u4 time delta since start, in usec +// +// Record format v3: +// u2 thread ID +// u4 method ID | method action +// u4 time delta since start, in usec +// u4 wall time since start, in usec (when clock == "dual" only) +// +// 32 bits of microseconds is 70 minutes. +// +// All values are stored in little-endian order. + static const uint32_t kTraceMethodActionMask = 0x03; // two bits static const char kTraceTokenChar = '*'; static const uint16_t kTraceHeaderLength = 32; @@ -41,44 +75,57 @@ static const uint16_t kTraceVersionDualClock = 3; static const uint16_t kTraceRecordSizeSingleClock = 10; // using v2 static const uint16_t kTraceRecordSizeDualClock = 14; // using v3 with two timestamps +static ProfilerClockSource gDefaultTraceClockSource = kProfilerClockSourceDual; + static inline uint32_t TraceMethodId(uint32_t methodValue) { return (methodValue & ~kTraceMethodActionMask); } + static inline uint32_t TraceMethodCombine(uint32_t method, uint8_t traceEvent) { return (method | traceEvent); } -static bool UseThreadCpuClock() { - // TODO: Allow control over which clock is used - return true; +void Trace::SetDefaultClockSource(ProfilerClockSource clock_source) { + gDefaultTraceClockSource = clock_source; +} + +bool Trace::UseThreadCpuClock() { +#if defined(HAVE_POSIX_CLOCKS) + return clock_source_ != kProfilerClockSourceWall; +#else + return false; +#endif } -static bool UseWallClock() { - // TODO: Allow control over which clock is used +bool Trace::UseWallClock() { +#if defined(HAVE_POSIX_CLOCKS) + return clock_source_ != kProfilerClockSourceThreadCpu; +#else return true; +#endif } -static void MeasureClockOverhead() { - if (UseThreadCpuClock()) { +static void MeasureClockOverhead(Trace* trace) { + if (trace->UseThreadCpuClock()) { ThreadCpuMicroTime(); } - if (UseWallClock()) { + if (trace->UseWallClock()) { MicroTime(); } } -static uint32_t GetClockOverhead() { +static uint32_t GetClockOverhead(Trace* trace) { uint64_t start = ThreadCpuMicroTime(); for (int i = 4000; i > 0; i--) { - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); - MeasureClockOverhead(); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); + MeasureClockOverhead(trace); } uint64_t elapsed = ThreadCpuMicroTime() - start; @@ -204,6 +251,12 @@ void Trace::ResetSavedCode(Method* method) { RemoveSavedCodeFromMap(method); } +Trace::Trace(File* trace_file, int buffer_size, int flags) + : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), + clock_source_(gDefaultTraceClockSource), overflow_(false), + buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) { +} + void Trace::Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms) { if (Runtime::Current()->IsMethodTracingActive()) { LOG(INFO) << "Trace already in progress, ignoring this request"; @@ -306,7 +359,7 @@ void Trace::FinishTracing() { uint64_t elapsed = MicroTime() - start_time_; size_t final_offset = cur_offset_; - uint32_t clock_overhead = GetClockOverhead(); + uint32_t clock_overhead = GetClockOverhead(this); if ((flags_ & kTraceCountAllocs) != 0) { Runtime::Current()->SetStatsEnabled(false); diff --git a/src/trace.h b/src/trace.h index bcf7f0a411..0042fc27fa 100644 --- a/src/trace.h +++ b/src/trace.h @@ -43,9 +43,14 @@ struct TraceStackFrame { uintptr_t return_pc_; }; +enum ProfilerClockSource { + kProfilerClockSourceThreadCpu, + kProfilerClockSourceWall, + kProfilerClockSourceDual, +}; + class Trace { public: - enum TraceEvent { kMethodTraceEnter = 0, kMethodTraceExit = 1, @@ -56,10 +61,15 @@ class Trace { kTraceCountAllocs = 1, }; + 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); static void Stop(); static void Shutdown(); + bool UseWallClock(); + bool UseThreadCpuClock(); + void LogMethodTraceEvent(Thread* self, const Method* method, TraceEvent event); void AddSavedCodeToMap(const Method* method, const void* code); @@ -70,10 +80,7 @@ class Trace { void ResetSavedCode(Method* method); private: - explicit Trace(File* trace_file, int buffer_size, int flags) - : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), overflow_(false), - buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) { - } + explicit Trace(File* trace_file, int buffer_size, int flags); void BeginTracing(); void FinishTracing(); @@ -107,6 +114,8 @@ class Trace { // Flags enabling extra tracing of things such as alloc counts. int flags_; + ProfilerClockSource clock_source_; + bool overflow_; int buffer_size_; uint64_t start_time_; |