blob: c8d29f8cf5747907e924fe3dd3643e324438024c [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
ricow@chromium.orgc9c80822010-04-21 08:22:37 +000032#ifdef ENABLE_LOGGING_AND_PROFILING
lrn@chromium.org25156de2010-04-06 13:10:27 +000033
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +000034#include "frames-inl.h"
lrn@chromium.org25156de2010-04-06 13:10:27 +000035#include "log-inl.h"
36
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
47ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
48 : generator_(generator),
49 running_(false),
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000050 ticks_buffer_(sizeof(TickSampleEventRecord),
51 kTickSamplesBufferChunkSize,
52 kTickSamplesBufferChunksCount),
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +000053 enqueue_order_(0) {
54}
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000055
56
lrn@chromium.org25156de2010-04-06 13:10:27 +000057void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
58 const char* prefix,
59 String* name,
60 Address start) {
ager@chromium.org357bf652010-04-12 11:30:10 +000061 if (FilterOutCodeCreateEvent(tag)) return;
lrn@chromium.org25156de2010-04-06 13:10:27 +000062 CodeEventsContainer evt_rec;
63 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
64 rec->type = CodeEventRecord::CODE_CREATION;
65 rec->order = ++enqueue_order_;
66 rec->start = start;
67 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
68 rec->size = 1;
69 events_buffer_.Enqueue(evt_rec);
70}
71
72
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000073void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
74 String* name,
75 String* resource_name,
76 int line_number,
77 Address start,
78 unsigned size) {
ager@chromium.org357bf652010-04-12 11:30:10 +000079 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000080 CodeEventsContainer evt_rec;
81 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
82 rec->type = CodeEventRecord::CODE_CREATION;
83 rec->order = ++enqueue_order_;
84 rec->start = start;
85 rec->entry = generator_->NewCodeEntry(tag, name, resource_name, line_number);
86 rec->size = size;
87 events_buffer_.Enqueue(evt_rec);
88}
89
90
91void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
92 const char* name,
93 Address start,
94 unsigned size) {
ager@chromium.org357bf652010-04-12 11:30:10 +000095 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000096 CodeEventsContainer evt_rec;
97 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
98 rec->type = CodeEventRecord::CODE_CREATION;
99 rec->order = ++enqueue_order_;
100 rec->start = start;
101 rec->entry = generator_->NewCodeEntry(tag, name);
102 rec->size = size;
103 events_buffer_.Enqueue(evt_rec);
104}
105
106
107void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
108 int args_count,
109 Address start,
110 unsigned size) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000111 if (FilterOutCodeCreateEvent(tag)) return;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000112 CodeEventsContainer evt_rec;
113 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
114 rec->type = CodeEventRecord::CODE_CREATION;
115 rec->order = ++enqueue_order_;
116 rec->start = start;
117 rec->entry = generator_->NewCodeEntry(tag, args_count);
118 rec->size = size;
119 events_buffer_.Enqueue(evt_rec);
120}
121
122
123void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
124 CodeEventsContainer evt_rec;
125 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
126 rec->type = CodeEventRecord::CODE_MOVE;
127 rec->order = ++enqueue_order_;
128 rec->from = from;
129 rec->to = to;
130 events_buffer_.Enqueue(evt_rec);
131}
132
133
134void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
135 CodeEventsContainer evt_rec;
136 CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
137 rec->type = CodeEventRecord::CODE_DELETE;
138 rec->order = ++enqueue_order_;
139 rec->start = from;
140 events_buffer_.Enqueue(evt_rec);
141}
142
143
144void ProfilerEventsProcessor::FunctionCreateEvent(Address alias,
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000145 Address start,
146 int security_token_id) {
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000147 CodeEventsContainer evt_rec;
148 CodeAliasEventRecord* rec = &evt_rec.CodeAliasEventRecord_;
149 rec->type = CodeEventRecord::CODE_ALIAS;
150 rec->order = ++enqueue_order_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000151 rec->start = alias;
152 rec->entry = generator_->NewCodeEntry(security_token_id);
153 rec->code_start = start;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000154 events_buffer_.Enqueue(evt_rec);
155}
156
157
158void ProfilerEventsProcessor::FunctionMoveEvent(Address from, Address to) {
159 CodeMoveEvent(from, to);
160}
161
162
163void ProfilerEventsProcessor::FunctionDeleteEvent(Address from) {
164 CodeDeleteEvent(from);
165}
166
167
ager@chromium.org357bf652010-04-12 11:30:10 +0000168void ProfilerEventsProcessor::RegExpCodeCreateEvent(
169 Logger::LogEventsAndTags tag,
170 const char* prefix,
171 String* name,
172 Address start,
173 unsigned size) {
174 if (FilterOutCodeCreateEvent(tag)) return;
175 CodeEventsContainer evt_rec;
176 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
177 rec->type = CodeEventRecord::CODE_CREATION;
178 rec->order = ++enqueue_order_;
179 rec->start = start;
180 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
181 rec->size = size;
182 events_buffer_.Enqueue(evt_rec);
183}
184
185
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000186void ProfilerEventsProcessor::AddCurrentStack() {
187 TickSampleEventRecord record;
188 TickSample* sample = &record.sample;
189 sample->state = VMState::current_state();
190 sample->pc = reinterpret_cast<Address>(sample); // Not NULL.
191 sample->frames_count = 0;
192 for (StackTraceFrameIterator it;
193 !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
194 it.Advance()) {
195 JavaScriptFrame* frame = it.frame();
196 sample->stack[sample->frames_count++] =
197 reinterpret_cast<Address>(frame->function());
198 }
199 record.order = enqueue_order_;
200 ticks_from_vm_buffer_.Enqueue(record);
201}
202
203
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000204bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) {
205 if (!events_buffer_.IsEmpty()) {
206 CodeEventsContainer record;
207 events_buffer_.Dequeue(&record);
208 switch (record.generic.type) {
209#define PROFILER_TYPE_CASE(type, clss) \
210 case CodeEventRecord::type: \
211 record.clss##_.UpdateCodeMap(generator_->code_map()); \
212 break;
213
214 CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE)
215
216#undef PROFILER_TYPE_CASE
217 default: return true; // Skip record.
218 }
219 *dequeue_order = record.generic.order;
220 return true;
221 }
222 return false;
223}
224
225
226bool ProfilerEventsProcessor::ProcessTicks(unsigned dequeue_order) {
227 while (true) {
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000228 if (!ticks_from_vm_buffer_.IsEmpty()
229 && ticks_from_vm_buffer_.Peek()->order == dequeue_order) {
230 TickSampleEventRecord record;
231 ticks_from_vm_buffer_.Dequeue(&record);
232 generator_->RecordTickSample(record.sample);
233 }
234
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000235 const TickSampleEventRecord* rec =
lrn@chromium.org25156de2010-04-06 13:10:27 +0000236 TickSampleEventRecord::cast(ticks_buffer_.StartDequeue());
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000237 if (rec == NULL) return !ticks_from_vm_buffer_.IsEmpty();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000238 if (rec->order == dequeue_order) {
239 generator_->RecordTickSample(rec->sample);
240 ticks_buffer_.FinishDequeue();
241 } else {
242 return true;
243 }
244 }
245}
246
247
248void ProfilerEventsProcessor::Run() {
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000249 unsigned dequeue_order = 0;
250 running_ = true;
251
252 while (running_) {
253 // Process ticks until we have any.
254 if (ProcessTicks(dequeue_order)) {
255 // All ticks of the current dequeue_order are processed,
256 // proceed to the next code event.
257 ProcessCodeEvent(&dequeue_order);
258 }
259 YieldCPU();
260 }
261
262 // Process remaining tick events.
263 ticks_buffer_.FlushResidualRecords();
264 // Perform processing until we have tick events, skip remaining code events.
265 while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000266}
267
268
lrn@chromium.org25156de2010-04-06 13:10:27 +0000269CpuProfiler* CpuProfiler::singleton_ = NULL;
270
271void CpuProfiler::StartProfiling(const char* title) {
272 ASSERT(singleton_ != NULL);
273 singleton_->StartCollectingProfile(title);
274}
275
276
277void CpuProfiler::StartProfiling(String* title) {
278 ASSERT(singleton_ != NULL);
279 singleton_->StartCollectingProfile(title);
280}
281
282
283CpuProfile* CpuProfiler::StopProfiling(const char* title) {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000284 return is_profiling() ? singleton_->StopCollectingProfile(title) : NULL;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000285}
286
287
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000288CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
289 return is_profiling() ?
290 singleton_->StopCollectingProfile(security_token, title) : NULL;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000291}
292
293
294int CpuProfiler::GetProfilesCount() {
295 ASSERT(singleton_ != NULL);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000296 // The count of profiles doesn't depend on a security token.
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000297 return singleton_->profiles_->Profiles(
298 TokenEnumerator::kNoSecurityToken)->length();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000299}
300
301
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000302CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000303 ASSERT(singleton_ != NULL);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000304 const int token = singleton_->token_enumerator_->GetTokenId(security_token);
305 return singleton_->profiles_->Profiles(token)->at(index);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000306}
307
308
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000309CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000310 ASSERT(singleton_ != NULL);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000311 const int token = singleton_->token_enumerator_->GetTokenId(security_token);
312 return singleton_->profiles_->GetProfile(token, uid);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000313}
314
315
316TickSample* CpuProfiler::TickSampleEvent() {
ager@chromium.org357bf652010-04-12 11:30:10 +0000317 if (CpuProfiler::is_profiling()) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000318 return singleton_->processor_->TickSampleEvent();
319 } else {
320 return NULL;
321 }
322}
323
324
325void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
326 singleton_->processor_->CallbackCreateEvent(
327 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
328}
329
330
331void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
332 Code* code, const char* comment) {
333 singleton_->processor_->CodeCreateEvent(
334 tag, comment, code->address(), code->ExecutableSize());
335}
336
337
338void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
339 Code* code, String* name) {
340 singleton_->processor_->CodeCreateEvent(
341 tag,
342 name,
343 Heap::empty_string(),
ager@chromium.org357bf652010-04-12 11:30:10 +0000344 v8::CpuProfileNode::kNoLineNumberInfo,
lrn@chromium.org25156de2010-04-06 13:10:27 +0000345 code->address(),
346 code->ExecutableSize());
347}
348
349
350void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
351 Code* code, String* name,
352 String* source, int line) {
353 singleton_->processor_->CodeCreateEvent(
354 tag,
355 name,
356 source,
357 line,
358 code->address(),
359 code->ExecutableSize());
360}
361
362
363void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
364 Code* code, int args_count) {
365 singleton_->processor_->CodeCreateEvent(
366 tag,
367 args_count,
368 code->address(),
369 code->ExecutableSize());
370}
371
372
373void CpuProfiler::CodeMoveEvent(Address from, Address to) {
374 singleton_->processor_->CodeMoveEvent(from, to);
375}
376
377
378void CpuProfiler::CodeDeleteEvent(Address from) {
379 singleton_->processor_->CodeDeleteEvent(from);
380}
381
382
383void CpuProfiler::FunctionCreateEvent(JSFunction* function) {
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000384 int security_token_id = TokenEnumerator::kNoSecurityToken;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000385 if (function->unchecked_context()->IsContext()) {
386 security_token_id = singleton_->token_enumerator_->GetTokenId(
387 function->context()->global_context()->security_token());
388 }
lrn@chromium.org25156de2010-04-06 13:10:27 +0000389 singleton_->processor_->FunctionCreateEvent(
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000390 function->address(),
391 function->code()->address(),
392 security_token_id);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000393}
394
395
396void CpuProfiler::FunctionMoveEvent(Address from, Address to) {
397 singleton_->processor_->FunctionMoveEvent(from, to);
398}
399
400
401void CpuProfiler::FunctionDeleteEvent(Address from) {
402 singleton_->processor_->FunctionDeleteEvent(from);
403}
404
405
406void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
407 singleton_->processor_->CallbackCreateEvent(
408 Logger::CALLBACK_TAG, "get ", name, entry_point);
409}
410
411
412void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000413 singleton_->processor_->RegExpCodeCreateEvent(
lrn@chromium.org25156de2010-04-06 13:10:27 +0000414 Logger::REG_EXP_TAG,
ager@chromium.org357bf652010-04-12 11:30:10 +0000415 "RegExp: ",
lrn@chromium.org25156de2010-04-06 13:10:27 +0000416 source,
lrn@chromium.org25156de2010-04-06 13:10:27 +0000417 code->address(),
418 code->ExecutableSize());
419}
420
421
422void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
423 singleton_->processor_->CallbackCreateEvent(
424 Logger::CALLBACK_TAG, "set ", name, entry_point);
425}
426
427
428CpuProfiler::CpuProfiler()
429 : profiles_(new CpuProfilesCollection()),
430 next_profile_uid_(1),
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000431 token_enumerator_(new TokenEnumerator()),
lrn@chromium.org25156de2010-04-06 13:10:27 +0000432 generator_(NULL),
433 processor_(NULL) {
434}
435
436
437CpuProfiler::~CpuProfiler() {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000438 delete token_enumerator_;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000439 delete profiles_;
440}
441
442
443void CpuProfiler::StartCollectingProfile(const char* title) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000444 if (profiles_->StartProfiling(title, next_profile_uid_++)) {
lrn@chromium.org25156de2010-04-06 13:10:27 +0000445 StartProcessorIfNotStarted();
446 }
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000447 processor_->AddCurrentStack();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000448}
449
450
451void CpuProfiler::StartCollectingProfile(String* title) {
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000452 StartCollectingProfile(profiles_->GetName(title));
lrn@chromium.org25156de2010-04-06 13:10:27 +0000453}
454
455
456void CpuProfiler::StartProcessorIfNotStarted() {
457 if (processor_ == NULL) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000458 // Disable logging when using the new implementation.
459 saved_logging_nesting_ = Logger::logging_nesting_;
460 Logger::logging_nesting_ = 0;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000461 generator_ = new ProfileGenerator(profiles_);
462 processor_ = new ProfilerEventsProcessor(generator_);
463 processor_->Start();
464 // Enumerate stuff we already have in the heap.
465 if (Heap::HasBeenSetup()) {
466 Logger::LogCodeObjects();
467 Logger::LogCompiledFunctions();
468 Logger::LogFunctionObjects();
469 Logger::LogAccessorCallbacks();
470 }
sgjesse@chromium.org82dbbab2010-06-02 08:57:44 +0000471 // Enable stack sampling.
472 reinterpret_cast<Sampler*>(Logger::ticker_)->Start();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000473 }
474}
475
476
477CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000478 const double actual_sampling_rate = generator_->actual_sampling_rate();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000479 StopProcessorIfLastProfile();
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000480 CpuProfile* result =
481 profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken,
482 title,
483 actual_sampling_rate);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000484 if (result != NULL) {
485 result->Print();
486 }
487 return result;
488}
489
490
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000491CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
492 String* title) {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000493 const double actual_sampling_rate = generator_->actual_sampling_rate();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000494 StopProcessorIfLastProfile();
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000495 int token = token_enumerator_->GetTokenId(security_token);
496 return profiles_->StopProfiling(token, title, actual_sampling_rate);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000497}
498
499
500void CpuProfiler::StopProcessorIfLastProfile() {
501 if (profiles_->is_last_profile()) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000502 reinterpret_cast<Sampler*>(Logger::ticker_)->Stop();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000503 processor_->Stop();
504 processor_->Join();
505 delete processor_;
506 delete generator_;
507 processor_ = NULL;
508 generator_ = NULL;
ager@chromium.org357bf652010-04-12 11:30:10 +0000509 Logger::logging_nesting_ = saved_logging_nesting_;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000510 }
511}
512
513} } // namespace v8::internal
514
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000515#endif // ENABLE_LOGGING_AND_PROFILING
lrn@chromium.org25156de2010-04-06 13:10:27 +0000516
517namespace v8 {
518namespace internal {
519
520void CpuProfiler::Setup() {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000521#ifdef ENABLE_LOGGING_AND_PROFILING
lrn@chromium.org25156de2010-04-06 13:10:27 +0000522 if (singleton_ == NULL) {
523 singleton_ = new CpuProfiler();
524 }
525#endif
526}
527
528
529void CpuProfiler::TearDown() {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000530#ifdef ENABLE_LOGGING_AND_PROFILING
lrn@chromium.org25156de2010-04-06 13:10:27 +0000531 if (singleton_ != NULL) {
532 delete singleton_;
533 }
534 singleton_ = NULL;
535#endif
536}
537
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000538} } // namespace v8::internal