Chromium Code Reviews| Index: runtime/vm/profiler.h |
| diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4ffdeb4c1cd7107a241213b6c8059c4d46e6c155 |
| --- /dev/null |
| +++ b/runtime/vm/profiler.h |
| @@ -0,0 +1,165 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#ifndef VM_PROFILER_H_ |
| +#define VM_PROFILER_H_ |
| + |
| +#include "platform/hashmap.h" |
| +#include "platform/thread.h" |
| +#include "vm/allocation.h" |
| +#include "vm/code_observers.h" |
| +#include "vm/globals.h" |
| + |
| +namespace dart { |
| + |
| + |
|
siva
2013/10/28 05:19:21
extra blank line?
Cutch
2013/11/04 20:36:05
Done.
|
| +// Profiler manager. |
| +class ProfilerManager : public AllStatic { |
| + public: |
| + static void InitOnce(); |
| + static void Shutdown(); |
| + |
| + static void SetupIsolateForProfiling(Isolate* isolate); |
| + static void ShutdownIsolate(Isolate* isolate); |
|
siva
2013/10/28 05:19:21
should be ShutdownIsolateProfiling
ShutdownIsolat
Cutch
2013/11/04 20:36:05
Done.
|
| + static void ScheduleIsolate(Isolate* isolate); |
| + static void DescheduleIsolate(Isolate* isolate); |
| + |
| + static void PrintToJSONStream(Isolate* isolate, JSONStream* stream); |
| + |
| + static void WriteTracing(Isolate* isolate, const char* name, Dart_Port port); |
| + |
| + private: |
| + static bool initialized_; |
| + static bool shutdown_; |
| + static Monitor* monitor_; |
| + |
| + static Isolate** isolates_; |
| + static intptr_t isolates_capacity_; |
| + static intptr_t isolates_size_; |
| + |
| + static void ResizeIsolates(intptr_t new_capacity); |
| + static void AddIsolate(Isolate* isolate); |
| + static intptr_t FindIsolate(Isolate* isolate); |
| + static void RemoveIsolate(intptr_t i); |
| + |
| + // Returns the microseconds until the next live timer fires. |
| + static int64_t SampleAndRescheduleIsolates(int64_t current_time); |
| + static void FreeIsolateProfilingData(Isolate* isolate); |
| + static void ThreadMain(uword parameters); |
|
siva
2013/10/28 05:19:21
DISALLOW_COPY stuff?
Cutch
2013/11/04 20:36:05
Done.
|
| +}; |
| + |
| + |
| +class IsolateProfilerData { |
| + public: |
| + static const int64_t kDescheduledCpuUsage = -1; |
| + static const int64_t kNoExpirationTime = -2; |
| + |
| + IsolateProfilerData(Isolate* isolate, SampleBuffer* sample_buffer); |
| + ~IsolateProfilerData(); |
| + |
| + int64_t sample_interval() const { return sample_interval_micros_; } |
| + |
| + void set_sample_interval(int64_t sample_interval) { |
| + sample_interval_micros_ = sample_interval; |
| + } |
| + |
| + bool CanExpire() { |
| + return timer_expiration_micros_ != kNoExpirationTime; |
| + } |
| + |
| + bool ShouldSample(int64_t current_time) { |
| + return CanExpire() && TimeUntilExpiration(current_time) <= 0; |
| + } |
| + |
| + int64_t TimeUntilExpiration(int64_t current_time) { |
|
siva
2013/10/28 05:19:21
maybe call it current_time_in_micros?
Cutch
2013/11/04 20:36:05
Done.
|
| + ASSERT(CanExpire()); |
| + return timer_expiration_micros_ - current_time; |
| + } |
| + |
| + void set_cpu_usage(int64_t cpu_usage) { |
| + cpu_usage_ = cpu_usage; |
| + } |
| + |
| + void SampledAt(int64_t current_time); |
| + |
| + void Scheduled(int64_t current_time, ThreadId thread); |
| + |
| + void Descheduled(); |
| + |
| + int64_t cpu_usage() const { return cpu_usage_; } |
| + |
| + int64_t set_and_delta_cpu_usage(int64_t cpu_usage) { |
| + int64_t delta = 0; |
| + if (cpu_usage_ != kDescheduledCpuUsage) { |
| + // Only compute the real delta if we are being sampled regularly. |
| + delta = cpu_usage - cpu_usage_; |
| + } |
| + set_cpu_usage(cpu_usage); |
| + return delta; |
| + } |
| + |
| + ThreadId thread_id() const { return thread_id_; } |
| + |
| + Isolate* isolate() const { return isolate_; } |
| + |
| + SampleBuffer* sample_buffer() const { return sample_buffer_; } |
| + |
| + private: |
| + int64_t last_sampled_micros_; |
| + int64_t timer_expiration_micros_; |
| + int64_t sample_interval_micros_; |
| + int64_t cpu_usage_; |
| + ThreadId thread_id_; |
| + Isolate* isolate_; |
| + SampleBuffer* sample_buffer_; |
|
siva
2013/10/28 05:19:21
DISALLOW stuff.
Cutch
2013/11/04 20:36:05
Done.
|
| +}; |
| + |
| + |
| +// Profile sample. |
| +struct Sample { |
| + static const char* kLookupSymbol; |
| + static const char* kNoSymbol; |
| + static const intptr_t kNumStackFrames = 4; |
| + enum SampleState { |
| + kIdle = 0, |
| + kExecuting = 1, |
| + kNumSampleStates |
| + }; |
| + int64_t timestamp; |
| + int64_t cpu_usage; |
| + uintptr_t pcs[kNumStackFrames]; |
| + uint16_t vm_tags; |
| + uint16_t runtime_tags; |
| + Sample(); |
| +}; |
| + |
| + |
| +// Ring buffer of samples. One per isolate. |
| +class SampleBuffer { |
| + public: |
| + static const intptr_t kDefaultBufferCapacity = 1000000; |
| + |
| + explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); |
| + ~SampleBuffer(); |
| + |
| + intptr_t capacity() const { return capacity_; } |
| + |
| + Sample* ReserveSample(); |
| + |
| + Sample* FirstSample() const; |
| + Sample* NextSample(Sample* sample) const; |
| + Sample* LastSample() const; |
| + private: |
| + Sample* samples_; |
| + intptr_t capacity_; |
| + intptr_t start_; |
| + intptr_t end_; |
| + |
| + intptr_t WrapIncrement(intptr_t i) const; |
|
siva
2013/10/28 05:19:21
DISALLOW_ stuff.
Cutch
2013/11/04 20:36:05
Done.
|
| +}; |
| + |
| + |
|
siva
2013/10/28 05:19:21
extra blank line?
Cutch
2013/11/04 20:36:05
Done.
|
| +} // namespace dart |
| + |
| +#endif // VM_PROFILER_H_ |