| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/cpu-profiler-inl.h" | 7 #include "src/cpu-profiler-inl.h" |
| 8 | 8 |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
| 11 #include "src/hashmap.h" | 11 #include "src/hashmap.h" |
| 12 #include "src/log-inl.h" | 12 #include "src/log-inl.h" |
| 13 #include "src/vm-state-inl.h" | 13 #include "src/vm-state-inl.h" |
| 14 | 14 |
| 15 #include "include/v8-profiler.h" | 15 #include "include/v8-profiler.h" |
| 16 | 16 |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 | 19 |
| 20 static const int kProfilerStackSize = 64 * KB; | 20 static const int kProfilerStackSize = 64 * KB; |
| 21 | 21 |
| 22 | 22 |
| 23 ProfilerEventsProcessor::ProfilerEventsProcessor( | 23 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator, |
| 24 ProfileGenerator* generator, | 24 Sampler* sampler, |
| 25 Sampler* sampler, | 25 base::TimeDelta period) |
| 26 base::TimeDelta period) | |
| 27 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), | 26 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), |
| 28 generator_(generator), | 27 generator_(generator), |
| 29 sampler_(sampler), | 28 sampler_(sampler), |
| 30 running_(true), | 29 running_(1), |
| 31 period_(period), | 30 period_(period), |
| 32 last_code_event_id_(0), last_processed_code_event_id_(0) { | 31 last_code_event_id_(0), |
| 33 } | 32 last_processed_code_event_id_(0) {} |
| 34 | 33 |
| 35 | 34 |
| 36 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { | 35 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { |
| 37 event.generic.order = ++last_code_event_id_; | 36 event.generic.order = ++last_code_event_id_; |
| 38 events_buffer_.Enqueue(event); | 37 events_buffer_.Enqueue(event); |
| 39 } | 38 } |
| 40 | 39 |
| 41 | 40 |
| 42 void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate) { | 41 void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate) { |
| 43 TickSampleEventRecord record(last_code_event_id_); | 42 TickSampleEventRecord record(last_code_event_id_); |
| 44 RegisterState regs; | 43 RegisterState regs; |
| 45 StackFrameIterator it(isolate); | 44 StackFrameIterator it(isolate); |
| 46 if (!it.done()) { | 45 if (!it.done()) { |
| 47 StackFrame* frame = it.frame(); | 46 StackFrame* frame = it.frame(); |
| 48 regs.sp = frame->sp(); | 47 regs.sp = frame->sp(); |
| 49 regs.fp = frame->fp(); | 48 regs.fp = frame->fp(); |
| 50 regs.pc = frame->pc(); | 49 regs.pc = frame->pc(); |
| 51 } | 50 } |
| 52 record.sample.Init(isolate, regs); | 51 record.sample.Init(isolate, regs); |
| 53 ticks_from_vm_buffer_.Enqueue(record); | 52 ticks_from_vm_buffer_.Enqueue(record); |
| 54 } | 53 } |
| 55 | 54 |
| 56 | 55 |
| 57 void ProfilerEventsProcessor::StopSynchronously() { | 56 void ProfilerEventsProcessor::StopSynchronously() { |
| 58 if (!running_) return; | 57 if (!base::NoBarrier_AtomicExchange(&running_, 0)) return; |
| 59 running_ = false; | |
| 60 Join(); | 58 Join(); |
| 61 } | 59 } |
| 62 | 60 |
| 63 | 61 |
| 64 bool ProfilerEventsProcessor::ProcessCodeEvent() { | 62 bool ProfilerEventsProcessor::ProcessCodeEvent() { |
| 65 CodeEventsContainer record; | 63 CodeEventsContainer record; |
| 66 if (events_buffer_.Dequeue(&record)) { | 64 if (events_buffer_.Dequeue(&record)) { |
| 67 switch (record.generic.type) { | 65 switch (record.generic.type) { |
| 68 #define PROFILER_TYPE_CASE(type, clss) \ | 66 #define PROFILER_TYPE_CASE(type, clss) \ |
| 69 case CodeEventRecord::type: \ | 67 case CodeEventRecord::type: \ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 100 if (record->order != last_processed_code_event_id_) { | 98 if (record->order != last_processed_code_event_id_) { |
| 101 return FoundSampleForNextCodeEvent; | 99 return FoundSampleForNextCodeEvent; |
| 102 } | 100 } |
| 103 generator_->RecordTickSample(record->sample); | 101 generator_->RecordTickSample(record->sample); |
| 104 ticks_buffer_.Remove(); | 102 ticks_buffer_.Remove(); |
| 105 return OneSampleProcessed; | 103 return OneSampleProcessed; |
| 106 } | 104 } |
| 107 | 105 |
| 108 | 106 |
| 109 void ProfilerEventsProcessor::Run() { | 107 void ProfilerEventsProcessor::Run() { |
| 110 while (running_) { | 108 while (!!base::NoBarrier_Load(&running_)) { |
| 111 base::ElapsedTimer timer; | 109 base::ElapsedTimer timer; |
| 112 timer.Start(); | 110 timer.Start(); |
| 113 // Keep processing existing events until we need to do next sample. | 111 // Keep processing existing events until we need to do next sample. |
| 114 do { | 112 do { |
| 115 if (FoundSampleForNextCodeEvent == ProcessOneSample()) { | 113 if (FoundSampleForNextCodeEvent == ProcessOneSample()) { |
| 116 // All ticks of the current last_processed_code_event_id_ are | 114 // All ticks of the current last_processed_code_event_id_ are |
| 117 // processed, proceed to the next code event. | 115 // processed, proceed to the next code event. |
| 118 ProcessCodeEvent(); | 116 ProcessCodeEvent(); |
| 119 } | 117 } |
| 120 } while (!timer.HasExpired(period_)); | 118 } while (!timer.HasExpired(period_)); |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; | 497 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; |
| 500 Builtins::Name id = static_cast<Builtins::Name>(i); | 498 Builtins::Name id = static_cast<Builtins::Name>(i); |
| 501 rec->start = builtins->builtin(id)->address(); | 499 rec->start = builtins->builtin(id)->address(); |
| 502 rec->builtin_id = id; | 500 rec->builtin_id = id; |
| 503 processor_->Enqueue(evt_rec); | 501 processor_->Enqueue(evt_rec); |
| 504 } | 502 } |
| 505 } | 503 } |
| 506 | 504 |
| 507 | 505 |
| 508 } } // namespace v8::internal | 506 } } // namespace v8::internal |
| OLD | NEW |