blob: 2bd62ad39042e9b671952e02e65d397fc79436bb [file] [log] [blame]
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "cpu-profiler-inl.h"
31
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +000032#include "frames-inl.h"
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000033#include "hashmap.h"
lrn@chromium.org25156de2010-04-06 13:10:27 +000034#include "log-inl.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "vm-state-inl.h"
lrn@chromium.org25156de2010-04-06 13:10:27 +000036
ager@chromium.org357bf652010-04-12 11:30:10 +000037#include "../include/v8-profiler.h"
38
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000039namespace v8 {
40namespace internal {
41
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000042static const int kEventsBufferSize = 256*KB;
43static const int kTickSamplesBufferChunkSize = 64*KB;
44static const int kTickSamplesBufferChunksCount = 16;
45
46
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000047ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
48 : Thread("v8:ProfEvntProc"),
lrn@chromium.org5d00b602011-01-05 09:51:43 +000049 generator_(generator),
erik.corry@gmail.com145eff52010-08-23 11:36:18 +000050 running_(true),
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000051 ticks_buffer_(sizeof(TickSampleEventRecord),
52 kTickSamplesBufferChunkSize,
53 kTickSamplesBufferChunksCount),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000054 enqueue_order_(0) {
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +000055}
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000056
57
lrn@chromium.org25156de2010-04-06 13:10:27 +000058void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
59 const char* prefix,
60 String* name,
61 Address start) {
ager@chromium.org357bf652010-04-12 11:30:10 +000062 if (FilterOutCodeCreateEvent(tag)) return;
lrn@chromium.org25156de2010-04-06 13:10:27 +000063 CodeEventsContainer evt_rec;
64 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
65 rec->type = CodeEventRecord::CODE_CREATION;
66 rec->order = ++enqueue_order_;
67 rec->start = start;
68 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
69 rec->size = 1;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +000070 rec->shared = NULL;
lrn@chromium.org25156de2010-04-06 13:10:27 +000071 events_buffer_.Enqueue(evt_rec);
72}
73
74
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000075void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
76 String* name,
77 String* resource_name,
78 int line_number,
79 Address start,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000080 unsigned size,
whesse@chromium.orgb08986c2011-03-14 16:13:42 +000081 Address shared) {
ager@chromium.org357bf652010-04-12 11:30:10 +000082 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000083 CodeEventsContainer evt_rec;
84 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
85 rec->type = CodeEventRecord::CODE_CREATION;
86 rec->order = ++enqueue_order_;
87 rec->start = start;
88 rec->entry = generator_->NewCodeEntry(tag, name, resource_name, line_number);
89 rec->size = size;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +000090 rec->shared = shared;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000091 events_buffer_.Enqueue(evt_rec);
92}
93
94
95void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
96 const char* name,
97 Address start,
98 unsigned size) {
ager@chromium.org357bf652010-04-12 11:30:10 +000099 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000100 CodeEventsContainer evt_rec;
101 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
102 rec->type = CodeEventRecord::CODE_CREATION;
103 rec->order = ++enqueue_order_;
104 rec->start = start;
105 rec->entry = generator_->NewCodeEntry(tag, name);
106 rec->size = size;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000107 rec->shared = NULL;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000108 events_buffer_.Enqueue(evt_rec);
109}
110
111
112void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
113 int args_count,
114 Address start,
115 unsigned size) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000116 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000117 CodeEventsContainer evt_rec;
118 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
119 rec->type = CodeEventRecord::CODE_CREATION;
120 rec->order = ++enqueue_order_;
121 rec->start = start;
122 rec->entry = generator_->NewCodeEntry(tag, args_count);
123 rec->size = size;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000124 rec->shared = NULL;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000125 events_buffer_.Enqueue(evt_rec);
126}
127
128
129void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
130 CodeEventsContainer evt_rec;
131 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
132 rec->type = CodeEventRecord::CODE_MOVE;
133 rec->order = ++enqueue_order_;
134 rec->from = from;
135 rec->to = to;
136 events_buffer_.Enqueue(evt_rec);
137}
138
139
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000140void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
141 Address to) {
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000142 CodeEventsContainer evt_rec;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000143 SharedFunctionInfoMoveEventRecord* rec =
144 &evt_rec.SharedFunctionInfoMoveEventRecord_;
145 rec->type = CodeEventRecord::SHARED_FUNC_MOVE;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000146 rec->order = ++enqueue_order_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000147 rec->from = from;
148 rec->to = to;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000149 events_buffer_.Enqueue(evt_rec);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000150}
151
152
ager@chromium.org357bf652010-04-12 11:30:10 +0000153void ProfilerEventsProcessor::RegExpCodeCreateEvent(
154 Logger::LogEventsAndTags tag,
155 const char* prefix,
156 String* name,
157 Address start,
158 unsigned size) {
159 if (FilterOutCodeCreateEvent(tag)) return;
160 CodeEventsContainer evt_rec;
161 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
162 rec->type = CodeEventRecord::CODE_CREATION;
163 rec->order = ++enqueue_order_;
164 rec->start = start;
165 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
166 rec->size = size;
167 events_buffer_.Enqueue(evt_rec);
168}
169
170
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000171void ProfilerEventsProcessor::AddCurrentStack() {
ager@chromium.org04921a82011-06-27 13:21:41 +0000172 TickSampleEventRecord record(enqueue_order_);
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000173 TickSample* sample = &record.sample;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000174 Isolate* isolate = Isolate::Current();
175 sample->state = isolate->current_vm_state();
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000176 sample->pc = reinterpret_cast<Address>(sample); // Not NULL.
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000177 for (StackTraceFrameIterator it(isolate);
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000178 !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
179 it.Advance()) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000180 sample->stack[sample->frames_count++] = it.frame()->pc();
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000181 }
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000182 ticks_from_vm_buffer_.Enqueue(record);
183}
184
185
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000186bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) {
187 if (!events_buffer_.IsEmpty()) {
188 CodeEventsContainer record;
189 events_buffer_.Dequeue(&record);
190 switch (record.generic.type) {
191#define PROFILER_TYPE_CASE(type, clss) \
192 case CodeEventRecord::type: \
193 record.clss##_.UpdateCodeMap(generator_->code_map()); \
194 break;
195
196 CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE)
197
198#undef PROFILER_TYPE_CASE
199 default: return true; // Skip record.
200 }
201 *dequeue_order = record.generic.order;
202 return true;
203 }
204 return false;
205}
206
207
208bool ProfilerEventsProcessor::ProcessTicks(unsigned dequeue_order) {
209 while (true) {
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000210 if (!ticks_from_vm_buffer_.IsEmpty()
211 && ticks_from_vm_buffer_.Peek()->order == dequeue_order) {
212 TickSampleEventRecord record;
213 ticks_from_vm_buffer_.Dequeue(&record);
214 generator_->RecordTickSample(record.sample);
215 }
216
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000217 const TickSampleEventRecord* rec =
lrn@chromium.org25156de2010-04-06 13:10:27 +0000218 TickSampleEventRecord::cast(ticks_buffer_.StartDequeue());
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000219 if (rec == NULL) return !ticks_from_vm_buffer_.IsEmpty();
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +0000220 // Make a local copy of tick sample record to ensure that it won't
221 // be modified as we are processing it. This is possible as the
222 // sampler writes w/o any sync to the queue, so if the processor
223 // will get far behind, a record may be modified right under its
224 // feet.
225 TickSampleEventRecord record = *rec;
226 if (record.order == dequeue_order) {
227 // A paranoid check to make sure that we don't get a memory overrun
228 // in case of frames_count having a wild value.
229 if (record.sample.frames_count < 0
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000230 || record.sample.frames_count > TickSample::kMaxFramesCount)
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +0000231 record.sample.frames_count = 0;
232 generator_->RecordTickSample(record.sample);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000233 ticks_buffer_.FinishDequeue();
234 } else {
235 return true;
236 }
237 }
238}
239
240
241void ProfilerEventsProcessor::Run() {
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000242 unsigned dequeue_order = 0;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000243
244 while (running_) {
245 // Process ticks until we have any.
246 if (ProcessTicks(dequeue_order)) {
247 // All ticks of the current dequeue_order are processed,
248 // proceed to the next code event.
249 ProcessCodeEvent(&dequeue_order);
250 }
251 YieldCPU();
252 }
253
254 // Process remaining tick events.
255 ticks_buffer_.FlushResidualRecords();
256 // Perform processing until we have tick events, skip remaining code events.
257 while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000258}
259
260
lrn@chromium.org25156de2010-04-06 13:10:27 +0000261void CpuProfiler::StartProfiling(const char* title) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000262 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
263 Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000264}
265
266
267void CpuProfiler::StartProfiling(String* title) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000268 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
269 Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000270}
271
272
273CpuProfile* CpuProfiler::StopProfiling(const char* title) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000274 Isolate* isolate = Isolate::Current();
275 return is_profiling(isolate) ?
276 isolate->cpu_profiler()->StopCollectingProfile(title) : NULL;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000277}
278
279
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000280CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000281 Isolate* isolate = Isolate::Current();
282 return is_profiling(isolate) ?
283 isolate->cpu_profiler()->StopCollectingProfile(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000284 security_token, title) : NULL;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000285}
286
287
288int CpuProfiler::GetProfilesCount() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000289 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000290 // The count of profiles doesn't depend on a security token.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000291 return Isolate::Current()->cpu_profiler()->profiles_->Profiles(
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000292 TokenEnumerator::kNoSecurityToken)->length();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000293}
294
295
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000296CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000297 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
298 CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
299 const int token = profiler->token_enumerator_->GetTokenId(security_token);
300 return profiler->profiles_->Profiles(token)->at(index);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000301}
302
303
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000304CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000305 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
306 CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
307 const int token = profiler->token_enumerator_->GetTokenId(security_token);
308 return profiler->profiles_->GetProfile(token, uid);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000309}
310
311
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000312TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) {
313 if (CpuProfiler::is_profiling(isolate)) {
314 return isolate->cpu_profiler()->processor_->TickSampleEvent();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000315 } else {
316 return NULL;
317 }
318}
319
320
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000321void CpuProfiler::DeleteAllProfiles() {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000322 Isolate* isolate = Isolate::Current();
323 ASSERT(isolate->cpu_profiler() != NULL);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000324 if (is_profiling(isolate)) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000325 isolate->cpu_profiler()->StopProcessor();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000326 }
lrn@chromium.org7516f052011-03-30 08:52:27 +0000327 isolate->cpu_profiler()->ResetProfiles();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000328}
329
330
331void CpuProfiler::DeleteProfile(CpuProfile* profile) {
332 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
333 Isolate::Current()->cpu_profiler()->profiles_->RemoveProfile(profile);
334 delete profile;
335}
336
337
338bool CpuProfiler::HasDetachedProfiles() {
339 ASSERT(Isolate::Current()->cpu_profiler() != NULL);
340 return Isolate::Current()->cpu_profiler()->profiles_->HasDetachedProfiles();
341}
342
343
lrn@chromium.org25156de2010-04-06 13:10:27 +0000344void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000345 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000346 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
347}
348
349
350void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
351 Code* code, const char* comment) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000352 Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000353 tag, comment, code->address(), code->ExecutableSize());
354}
355
356
357void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
358 Code* code, String* name) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000359 Isolate* isolate = Isolate::Current();
360 isolate->cpu_profiler()->processor_->CodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000361 tag,
362 name,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000363 isolate->heap()->empty_string(),
ager@chromium.org357bf652010-04-12 11:30:10 +0000364 v8::CpuProfileNode::kNoLineNumberInfo,
lrn@chromium.org25156de2010-04-06 13:10:27 +0000365 code->address(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000366 code->ExecutableSize(),
367 NULL);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000368}
369
370
371void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000372 Code* code,
373 SharedFunctionInfo* shared,
374 String* name) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000375 Isolate* isolate = Isolate::Current();
376 isolate->cpu_profiler()->processor_->CodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000377 tag,
378 name,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000379 isolate->heap()->empty_string(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000380 v8::CpuProfileNode::kNoLineNumberInfo,
381 code->address(),
382 code->ExecutableSize(),
383 shared->address());
384}
385
386
387void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
388 Code* code,
389 SharedFunctionInfo* shared,
390 String* source, int line) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000391 Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000392 tag,
393 shared->DebugName(),
lrn@chromium.org25156de2010-04-06 13:10:27 +0000394 source,
395 line,
396 code->address(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000397 code->ExecutableSize(),
398 shared->address());
lrn@chromium.org25156de2010-04-06 13:10:27 +0000399}
400
401
402void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
403 Code* code, int args_count) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000404 Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000405 tag,
406 args_count,
407 code->address(),
408 code->ExecutableSize());
409}
410
411
412void CpuProfiler::CodeMoveEvent(Address from, Address to) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000413 Isolate::Current()->cpu_profiler()->processor_->CodeMoveEvent(from, to);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000414}
415
416
417void CpuProfiler::CodeDeleteEvent(Address from) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000418}
419
420
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000421void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000422 CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
423 profiler->processor_->SharedFunctionInfoMoveEvent(from, to);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000424}
425
426
427void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000428 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000429 Logger::CALLBACK_TAG, "get ", name, entry_point);
430}
431
432
433void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000434 Isolate::Current()->cpu_profiler()->processor_->RegExpCodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000435 Logger::REG_EXP_TAG,
ager@chromium.org357bf652010-04-12 11:30:10 +0000436 "RegExp: ",
lrn@chromium.org25156de2010-04-06 13:10:27 +0000437 source,
lrn@chromium.org25156de2010-04-06 13:10:27 +0000438 code->address(),
439 code->ExecutableSize());
440}
441
442
443void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000444 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000445 Logger::CALLBACK_TAG, "set ", name, entry_point);
446}
447
448
449CpuProfiler::CpuProfiler()
450 : profiles_(new CpuProfilesCollection()),
451 next_profile_uid_(1),
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000452 token_enumerator_(new TokenEnumerator()),
lrn@chromium.org25156de2010-04-06 13:10:27 +0000453 generator_(NULL),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000454 processor_(NULL),
455 need_to_stop_sampler_(false),
456 is_profiling_(false) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000457}
458
459
460CpuProfiler::~CpuProfiler() {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000461 delete token_enumerator_;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000462 delete profiles_;
463}
464
465
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000466void CpuProfiler::ResetProfiles() {
467 delete profiles_;
468 profiles_ = new CpuProfilesCollection();
469}
470
lrn@chromium.org25156de2010-04-06 13:10:27 +0000471void CpuProfiler::StartCollectingProfile(const char* title) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000472 if (profiles_->StartProfiling(title, next_profile_uid_++)) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000473 StartProcessorIfNotStarted();
474 }
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000475 processor_->AddCurrentStack();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000476}
477
478
479void CpuProfiler::StartCollectingProfile(String* title) {
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000480 StartCollectingProfile(profiles_->GetName(title));
lrn@chromium.org25156de2010-04-06 13:10:27 +0000481}
482
483
484void CpuProfiler::StartProcessorIfNotStarted() {
485 if (processor_ == NULL) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000486 Isolate* isolate = Isolate::Current();
487
ager@chromium.org357bf652010-04-12 11:30:10 +0000488 // Disable logging when using the new implementation.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000489 saved_logging_nesting_ = isolate->logger()->logging_nesting_;
490 isolate->logger()->logging_nesting_ = 0;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000491 generator_ = new ProfileGenerator(profiles_);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000492 processor_ = new ProfilerEventsProcessor(generator_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000493 NoBarrier_Store(&is_profiling_, true);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000494 processor_->Start();
495 // Enumerate stuff we already have in the heap.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000496 if (isolate->heap()->HasBeenSetUp()) {
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000497 if (!FLAG_prof_browser_mode) {
498 bool saved_log_code_flag = FLAG_log_code;
499 FLAG_log_code = true;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000500 isolate->logger()->LogCodeObjects();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000501 FLAG_log_code = saved_log_code_flag;
502 }
lrn@chromium.org7516f052011-03-30 08:52:27 +0000503 isolate->logger()->LogCompiledFunctions();
504 isolate->logger()->LogAccessorCallbacks();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000505 }
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000506 // Enable stack sampling.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000507 Sampler* sampler = reinterpret_cast<Sampler*>(isolate->logger()->ticker_);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000508 if (!sampler->IsActive()) {
509 sampler->Start();
510 need_to_stop_sampler_ = true;
511 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000512 sampler->IncreaseProfilingDepth();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000513 }
514}
515
516
517CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000518 const double actual_sampling_rate = generator_->actual_sampling_rate();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000519 StopProcessorIfLastProfile(title);
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000520 CpuProfile* result =
521 profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken,
522 title,
523 actual_sampling_rate);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000524 if (result != NULL) {
525 result->Print();
526 }
527 return result;
528}
529
530
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000531CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
532 String* title) {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000533 const double actual_sampling_rate = generator_->actual_sampling_rate();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000534 const char* profile_title = profiles_->GetName(title);
535 StopProcessorIfLastProfile(profile_title);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000536 int token = token_enumerator_->GetTokenId(security_token);
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000537 return profiles_->StopProfiling(token, profile_title, actual_sampling_rate);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000538}
539
540
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000541void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000542 if (profiles_->IsLastProfile(title)) StopProcessor();
543}
544
545
546void CpuProfiler::StopProcessor() {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000547 Logger* logger = Isolate::Current()->logger();
548 Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 sampler->DecreaseProfilingDepth();
550 if (need_to_stop_sampler_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551 sampler->Stop();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000552 need_to_stop_sampler_ = false;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000553 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000554 NoBarrier_Store(&is_profiling_, false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000555 processor_->Stop();
556 processor_->Join();
557 delete processor_;
558 delete generator_;
559 processor_ = NULL;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000560 generator_ = NULL;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000561 logger->logging_nesting_ = saved_logging_nesting_;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000562}
563
lrn@chromium.org25156de2010-04-06 13:10:27 +0000564
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000565void CpuProfiler::SetUp() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 Isolate* isolate = Isolate::Current();
567 if (isolate->cpu_profiler() == NULL) {
568 isolate->set_cpu_profiler(new CpuProfiler());
lrn@chromium.org25156de2010-04-06 13:10:27 +0000569 }
lrn@chromium.org25156de2010-04-06 13:10:27 +0000570}
571
572
573void CpuProfiler::TearDown() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 Isolate* isolate = Isolate::Current();
575 if (isolate->cpu_profiler() != NULL) {
576 delete isolate->cpu_profiler();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000577 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000578 isolate->set_cpu_profiler(NULL);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000579}
580
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000581} } // namespace v8::internal