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_ |