| Index: src/profile-generator.h
|
| diff --git a/src/profile-generator.h b/src/profile-generator.h
|
| index 7861ccd81785f3670a3d609ede6321717e0d5eac..6b02368816e540f10a45b1938822b713ab6d16e9 100644
|
| --- a/src/profile-generator.h
|
| +++ b/src/profile-generator.h
|
| @@ -203,11 +203,13 @@ class ProfileTree {
|
|
|
| class CpuProfile {
|
| public:
|
| - CpuProfile(const char* title, unsigned uid, bool record_samples);
|
| + CpuProfile(const char* title, unsigned uid, bool record_samples)
|
| + : title_(title), uid_(uid), record_samples_(record_samples) { }
|
|
|
| // Add pc -> ... -> main() call path to the profile.
|
| void AddPath(const Vector<CodeEntry*>& path);
|
| - void CalculateTotalTicksAndSamplingRate();
|
| + void CalculateTotalTicks();
|
| + void SetActualSamplingRate(double actual_sampling_rate);
|
|
|
| INLINE(const char* title() const) { return title_; }
|
| INLINE(unsigned uid() const) { return uid_; }
|
| @@ -225,8 +227,6 @@ class CpuProfile {
|
| const char* title_;
|
| unsigned uid_;
|
| bool record_samples_;
|
| - double start_time_ms_;
|
| - double end_time_ms_;
|
| List<ProfileNode*> samples_;
|
| ProfileTree top_down_;
|
|
|
| @@ -286,7 +286,7 @@ class CpuProfilesCollection {
|
| ~CpuProfilesCollection();
|
|
|
| bool StartProfiling(const char* title, unsigned uid, bool record_samples);
|
| - CpuProfile* StopProfiling(const char* title);
|
| + CpuProfile* StopProfiling(const char* title, double actual_sampling_rate);
|
| List<CpuProfile*>* profiles() { return &finished_profiles_; }
|
| const char* GetName(Name* name) {
|
| return function_and_resource_names_.GetName(name);
|
| @@ -329,6 +329,44 @@ class CpuProfilesCollection {
|
| };
|
|
|
|
|
| +class SampleRateCalculator {
|
| + public:
|
| + SampleRateCalculator()
|
| + : result_(Logger::kSamplingIntervalMs * kResultScale),
|
| + ticks_per_ms_(Logger::kSamplingIntervalMs),
|
| + measurements_count_(0),
|
| + wall_time_query_countdown_(1) {
|
| + }
|
| +
|
| + double ticks_per_ms() {
|
| + return result_ / static_cast<double>(kResultScale);
|
| + }
|
| + void Tick();
|
| + void UpdateMeasurements(double current_time);
|
| +
|
| + // Instead of querying current wall time each tick,
|
| + // we use this constant to control query intervals.
|
| + static const unsigned kWallTimeQueryIntervalMs = 100;
|
| +
|
| + private:
|
| + // As the result needs to be accessed from a different thread, we
|
| + // use type that guarantees atomic writes to memory. There should
|
| + // be <= 1000 ticks per second, thus storing a value of a 10 ** 5
|
| + // order should provide enough precision while keeping away from a
|
| + // potential overflow.
|
| + static const int kResultScale = 100000;
|
| +
|
| + AtomicWord result_;
|
| + // All other fields are accessed only from the sampler thread.
|
| + double ticks_per_ms_;
|
| + unsigned measurements_count_;
|
| + unsigned wall_time_query_countdown_;
|
| + double last_wall_time_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SampleRateCalculator);
|
| +};
|
| +
|
| +
|
| class ProfileGenerator {
|
| public:
|
| explicit ProfileGenerator(CpuProfilesCollection* profiles);
|
| @@ -337,6 +375,11 @@ class ProfileGenerator {
|
|
|
| INLINE(CodeMap* code_map()) { return &code_map_; }
|
|
|
| + INLINE(void Tick()) { sample_rate_calc_.Tick(); }
|
| + INLINE(double actual_sampling_rate()) {
|
| + return sample_rate_calc_.ticks_per_ms();
|
| + }
|
| +
|
| static const char* const kAnonymousFunctionName;
|
| static const char* const kProgramEntryName;
|
| static const char* const kGarbageCollectorEntryName;
|
| @@ -352,6 +395,7 @@ class ProfileGenerator {
|
| CodeEntry* program_entry_;
|
| CodeEntry* gc_entry_;
|
| CodeEntry* unresolved_entry_;
|
| + SampleRateCalculator sample_rate_calc_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
|
| };
|
|
|