Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: src/profiler/cpu-profiler.cc

Issue 2053523003: Refactor CpuProfiler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/profiler/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/profiler/cpu-profiler.h" 5 #include "src/profiler/cpu-profiler.h"
6 6
7 #include "src/debug/debug.h" 7 #include "src/debug/debug.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/frames-inl.h" 9 #include "src/frames-inl.h"
10 #include "src/locked-queue-inl.h" 10 #include "src/locked-queue-inl.h"
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 192
193 void CpuProfiler::DeleteProfile(CpuProfile* profile) { 193 void CpuProfiler::DeleteProfile(CpuProfile* profile) {
194 profiles_->RemoveProfile(profile); 194 profiles_->RemoveProfile(profile);
195 delete profile; 195 delete profile;
196 if (profiles_->profiles()->is_empty() && !is_profiling_) { 196 if (profiles_->profiles()->is_empty() && !is_profiling_) {
197 // If this was the last profile, clean up all accessory data as well. 197 // If this was the last profile, clean up all accessory data as well.
198 ResetProfiles(); 198 ResetProfiles();
199 } 199 }
200 } 200 }
201 201
202 202 void CpuProfiler::CodeEventHandler(const CodeEventsContainer& evt_rec) {
203 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { 203 switch (evt_rec.generic.type) {
204 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 204 case CodeEventRecord::CODE_CREATION:
205 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 205 case CodeEventRecord::CODE_MOVE:
206 rec->start = entry_point; 206 case CodeEventRecord::CODE_DISABLE_OPT:
207 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG, 207 processor_->Enqueue(evt_rec);
208 profiles_->GetName(name)); 208 break;
209 rec->size = 1; 209 case CodeEventRecord::CODE_DEOPT: {
210 processor_->Enqueue(evt_rec); 210 const CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
211 } 211 Address pc = reinterpret_cast<Address>(rec->pc);
212 212 int fp_to_sp_delta = rec->fp_to_sp_delta;
213 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, 213 processor_->Enqueue(evt_rec);
214 AbstractCode* code, const char* name) { 214 processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta);
215 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 215 break;
216 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
217 rec->start = code->address();
218 rec->entry = profiles_->NewCodeEntry(
219 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
220 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
221 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
222 RecordInliningInfo(rec->entry, code);
223 rec->size = code->ExecutableSize();
224 processor_->Enqueue(evt_rec);
225 }
226
227 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
228 AbstractCode* code, Name* name) {
229 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
230 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
231 rec->start = code->address();
232 rec->entry = profiles_->NewCodeEntry(
233 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
234 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
235 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
236 RecordInliningInfo(rec->entry, code);
237 rec->size = code->ExecutableSize();
238 processor_->Enqueue(evt_rec);
239 }
240
241 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
242 AbstractCode* code,
243 SharedFunctionInfo* shared,
244 Name* script_name) {
245 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
246 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
247 rec->start = code->address();
248 rec->entry = profiles_->NewCodeEntry(
249 tag, profiles_->GetFunctionName(shared->DebugName()),
250 CodeEntry::kEmptyNamePrefix,
251 profiles_->GetName(InferScriptName(script_name, shared)),
252 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
253 NULL, code->instruction_start());
254 RecordInliningInfo(rec->entry, code);
255 rec->entry->FillFunctionInfo(shared);
256 rec->size = code->ExecutableSize();
257 processor_->Enqueue(evt_rec);
258 }
259
260 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
261 AbstractCode* abstract_code,
262 SharedFunctionInfo* shared, Name* script_name,
263 int line, int column) {
264 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
265 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
266 rec->start = abstract_code->address();
267 Script* script = Script::cast(shared->script());
268 JITLineInfoTable* line_table = NULL;
269 if (script) {
270 if (abstract_code->IsCode()) {
271 Code* code = abstract_code->GetCode();
272 int start_position = shared->start_position();
273 int end_position = shared->end_position();
274 line_table = new JITLineInfoTable();
275 for (RelocIterator it(code); !it.done(); it.next()) {
276 RelocInfo* reloc_info = it.rinfo();
277 if (!RelocInfo::IsPosition(reloc_info->rmode())) continue;
278 int position = static_cast<int>(reloc_info->data());
279 // TODO(alph): in case of inlining the position may correspond
280 // to an inlined function source code. Do not collect positions
281 // that fall beyond the function source code. There's however a
282 // chance the inlined function has similar positions but in another
283 // script. So the proper fix is to store script_id in some form
284 // along with the inlined function positions.
285 if (position < start_position || position >= end_position) continue;
286 int pc_offset = static_cast<int>(reloc_info->pc() - code->address());
287 int line_number = script->GetLineNumber(position) + 1;
288 line_table->SetPosition(pc_offset, line_number);
289 }
290 } else {
291 BytecodeArray* bytecode = abstract_code->GetBytecodeArray();
292 line_table = new JITLineInfoTable();
293 interpreter::SourcePositionTableIterator it(
294 bytecode->source_position_table());
295 for (; !it.done(); it.Advance()) {
296 int line_number = script->GetLineNumber(it.source_position()) + 1;
297 int pc_offset = it.bytecode_offset() + BytecodeArray::kHeaderSize;
298 line_table->SetPosition(pc_offset, line_number);
299 }
300 } 216 }
301 } 217 default:
302 rec->entry = profiles_->NewCodeEntry( 218 UNREACHABLE();
303 tag, profiles_->GetFunctionName(shared->DebugName()),
304 CodeEntry::kEmptyNamePrefix,
305 profiles_->GetName(InferScriptName(script_name, shared)), line, column,
306 line_table, abstract_code->instruction_start());
307 RecordInliningInfo(rec->entry, abstract_code);
308 RecordDeoptInlinedFrames(rec->entry, abstract_code);
309 rec->entry->FillFunctionInfo(shared);
310 rec->size = abstract_code->ExecutableSize();
311 processor_->Enqueue(evt_rec);
312 }
313
314 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
315 AbstractCode* code, int args_count) {
316 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
317 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
318 rec->start = code->address();
319 rec->entry = profiles_->NewCodeEntry(
320 tag, profiles_->GetName(args_count), "args_count: ",
321 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
322 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
323 RecordInliningInfo(rec->entry, code);
324 rec->size = code->ExecutableSize();
325 processor_->Enqueue(evt_rec);
326 }
327
328 void CpuProfiler::CodeMoveEvent(AbstractCode* from, Address to) {
329 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
330 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
331 rec->from = from->address();
332 rec->to = to;
333 processor_->Enqueue(evt_rec);
334 }
335
336 void CpuProfiler::CodeDisableOptEvent(AbstractCode* code,
337 SharedFunctionInfo* shared) {
338 CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
339 CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
340 rec->start = code->address();
341 rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
342 processor_->Enqueue(evt_rec);
343 }
344
345 void CpuProfiler::CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) {
346 CodeEventsContainer evt_rec(CodeEventRecord::CODE_DEOPT);
347 CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
348 Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc);
349 rec->start = code->address();
350 rec->deopt_reason = Deoptimizer::GetDeoptReason(info.deopt_reason);
351 rec->position = info.position;
352 rec->deopt_id = info.deopt_id;
353 processor_->Enqueue(evt_rec);
354 processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta);
355 }
356
357 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
358 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
359 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
360 rec->start = entry_point;
361 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG,
362 profiles_->GetName(name), "get ");
363 rec->size = 1;
364 processor_->Enqueue(evt_rec);
365 }
366
367 void CpuProfiler::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
368 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
369 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
370 rec->start = code->address();
371 rec->entry = profiles_->NewCodeEntry(
372 CodeEventListener::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ",
373 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
374 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
375 rec->size = code->ExecutableSize();
376 processor_->Enqueue(evt_rec);
377 }
378
379
380 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
381 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
382 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
383 rec->start = entry_point;
384 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG,
385 profiles_->GetName(name), "set ");
386 rec->size = 1;
387 processor_->Enqueue(evt_rec);
388 }
389
390 Name* CpuProfiler::InferScriptName(Name* name, SharedFunctionInfo* info) {
391 if (name->IsString() && String::cast(name)->length()) return name;
392 if (!info->script()->IsScript()) return name;
393 Object* source_url = Script::cast(info->script())->source_url();
394 return source_url->IsName() ? Name::cast(source_url) : name;
395 }
396
397 void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
398 AbstractCode* abstract_code) {
399 if (!abstract_code->IsCode()) return;
400 Code* code = abstract_code->GetCode();
401 if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
402 DeoptimizationInputData* deopt_input_data =
403 DeoptimizationInputData::cast(code->deoptimization_data());
404 int deopt_count = deopt_input_data->DeoptCount();
405 for (int i = 0; i < deopt_count; i++) {
406 int pc_offset = deopt_input_data->Pc(i)->value();
407 if (pc_offset == -1) continue;
408 int translation_index = deopt_input_data->TranslationIndex(i)->value();
409 TranslationIterator it(deopt_input_data->TranslationByteArray(),
410 translation_index);
411 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
412 DCHECK_EQ(Translation::BEGIN, opcode);
413 it.Skip(Translation::NumberOfOperandsFor(opcode));
414 int depth = 0;
415 std::vector<CodeEntry*> inline_stack;
416 while (it.HasNext() &&
417 Translation::BEGIN !=
418 (opcode = static_cast<Translation::Opcode>(it.Next()))) {
419 if (opcode != Translation::JS_FRAME &&
420 opcode != Translation::INTERPRETED_FRAME) {
421 it.Skip(Translation::NumberOfOperandsFor(opcode));
422 continue;
423 }
424 it.Next(); // Skip ast_id
425 int shared_info_id = it.Next();
426 it.Next(); // Skip height
427 SharedFunctionInfo* shared_info = SharedFunctionInfo::cast(
428 deopt_input_data->LiteralArray()->get(shared_info_id));
429 if (!depth++) continue; // Skip the current function itself.
430 CodeEntry* inline_entry = new CodeEntry(
431 entry->tag(), profiles_->GetFunctionName(shared_info->DebugName()),
432 CodeEntry::kEmptyNamePrefix, entry->resource_name(),
433 CpuProfileNode::kNoLineNumberInfo,
434 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
435 inline_entry->FillFunctionInfo(shared_info);
436 inline_stack.push_back(inline_entry);
437 }
438 if (!inline_stack.empty()) {
439 entry->AddInlineStack(pc_offset, inline_stack);
440 DCHECK(inline_stack.empty());
441 }
442 } 219 }
443 } 220 }
444 221
445 void CpuProfiler::RecordDeoptInlinedFrames(CodeEntry* entry,
446 AbstractCode* abstract_code) {
447 if (abstract_code->kind() != AbstractCode::OPTIMIZED_FUNCTION) return;
448 Code* code = abstract_code->GetCode();
449 DeoptimizationInputData* deopt_input_data =
450 DeoptimizationInputData::cast(code->deoptimization_data());
451 int const mask = RelocInfo::ModeMask(RelocInfo::DEOPT_ID);
452 for (RelocIterator rit(code, mask); !rit.done(); rit.next()) {
453 RelocInfo* reloc_info = rit.rinfo();
454 DCHECK(RelocInfo::IsDeoptId(reloc_info->rmode()));
455 int deopt_id = static_cast<int>(reloc_info->data());
456 int translation_index =
457 deopt_input_data->TranslationIndex(deopt_id)->value();
458 TranslationIterator it(deopt_input_data->TranslationByteArray(),
459 translation_index);
460 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
461 DCHECK_EQ(Translation::BEGIN, opcode);
462 it.Skip(Translation::NumberOfOperandsFor(opcode));
463 std::vector<CodeEntry::DeoptInlinedFrame> inlined_frames;
464 while (it.HasNext() &&
465 Translation::BEGIN !=
466 (opcode = static_cast<Translation::Opcode>(it.Next()))) {
467 if (opcode != Translation::JS_FRAME &&
468 opcode != Translation::INTERPRETED_FRAME) {
469 it.Skip(Translation::NumberOfOperandsFor(opcode));
470 continue;
471 }
472 BailoutId ast_id = BailoutId(it.Next());
473 int shared_info_id = it.Next();
474 it.Next(); // Skip height
475 SharedFunctionInfo* shared = SharedFunctionInfo::cast(
476 deopt_input_data->LiteralArray()->get(shared_info_id));
477 int source_position = Deoptimizer::ComputeSourcePosition(shared, ast_id);
478 int script_id = v8::UnboundScript::kNoScriptId;
479 if (shared->script()->IsScript()) {
480 Script* script = Script::cast(shared->script());
481 script_id = script->id();
482 }
483 CodeEntry::DeoptInlinedFrame frame = {source_position, script_id};
484 inlined_frames.push_back(frame);
485 }
486 if (!inlined_frames.empty() && !entry->HasDeoptInlinedFramesFor(deopt_id)) {
487 entry->AddDeoptInlinedFrames(deopt_id, inlined_frames);
488 DCHECK(inlined_frames.empty());
489 }
490 }
491 }
492
493 CpuProfiler::CpuProfiler(Isolate* isolate) 222 CpuProfiler::CpuProfiler(Isolate* isolate)
494 : isolate_(isolate), 223 : isolate_(isolate),
495 sampling_interval_(base::TimeDelta::FromMicroseconds( 224 sampling_interval_(base::TimeDelta::FromMicroseconds(
496 FLAG_cpu_profiler_sampling_interval)), 225 FLAG_cpu_profiler_sampling_interval)),
497 profiles_(new CpuProfilesCollection(isolate)), 226 profiles_(new CpuProfilesCollection(isolate)),
498 is_profiling_(false) { 227 is_profiling_(false) {
499 profiles_->set_cpu_profiler(this); 228 profiles_->set_cpu_profiler(this);
500 } 229 }
501 230
502 CpuProfiler::CpuProfiler(Isolate* isolate, CpuProfilesCollection* test_profiles, 231 CpuProfiler::CpuProfiler(Isolate* isolate, CpuProfilesCollection* test_profiles,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 return; 280 return;
552 } 281 }
553 Logger* logger = isolate_->logger(); 282 Logger* logger = isolate_->logger();
554 // Disable logging when using the new implementation. 283 // Disable logging when using the new implementation.
555 saved_is_logging_ = logger->is_logging_; 284 saved_is_logging_ = logger->is_logging_;
556 logger->is_logging_ = false; 285 logger->is_logging_ = false;
557 sampler::Sampler* sampler = logger->sampler(); 286 sampler::Sampler* sampler = logger->sampler();
558 generator_.reset(new ProfileGenerator(profiles_.get())); 287 generator_.reset(new ProfileGenerator(profiles_.get()));
559 processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler, 288 processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler,
560 sampling_interval_)); 289 sampling_interval_));
290 logger->SetUpProfilerListener();
291 ProfilerListener* profiler_listener = logger->profiler_listener();
292 profiler_listener->AddObserver(this);
561 is_profiling_ = true; 293 is_profiling_ = true;
562 isolate_->set_is_profiling(true); 294 isolate_->set_is_profiling(true);
563 // Enumerate stuff we already have in the heap. 295 // Enumerate stuff we already have in the heap.
564 DCHECK(isolate_->heap()->HasBeenSetUp()); 296 DCHECK(isolate_->heap()->HasBeenSetUp());
565 isolate_->code_event_dispatcher()->AddListener(this);
566 if (!FLAG_prof_browser_mode) { 297 if (!FLAG_prof_browser_mode) {
567 logger->LogCodeObjects(); 298 logger->LogCodeObjects();
568 } 299 }
569 logger->LogCompiledFunctions(); 300 logger->LogCompiledFunctions();
570 logger->LogAccessorCallbacks(); 301 logger->LogAccessorCallbacks();
571 LogBuiltins(); 302 LogBuiltins();
572 // Enable stack sampling. 303 // Enable stack sampling.
573 sampler->SetHasProcessingThread(true); 304 sampler->SetHasProcessingThread(true);
574 sampler->IncreaseProfilingDepth(); 305 sampler->IncreaseProfilingDepth();
575 processor_->AddCurrentStack(isolate_); 306 processor_->AddCurrentStack(isolate_);
(...skipping 26 matching lines...) Expand all
602 } 333 }
603 } 334 }
604 335
605 336
606 void CpuProfiler::StopProcessor() { 337 void CpuProfiler::StopProcessor() {
607 Logger* logger = isolate_->logger(); 338 Logger* logger = isolate_->logger();
608 sampler::Sampler* sampler = 339 sampler::Sampler* sampler =
609 reinterpret_cast<sampler::Sampler*>(logger->ticker_); 340 reinterpret_cast<sampler::Sampler*>(logger->ticker_);
610 is_profiling_ = false; 341 is_profiling_ = false;
611 isolate_->set_is_profiling(false); 342 isolate_->set_is_profiling(false);
612 isolate_->code_event_dispatcher()->RemoveListener(this); 343 ProfilerListener* profiler_listener = logger->profiler_listener();
344 profiler_listener->RemoveObserver(this);
613 processor_->StopSynchronously(); 345 processor_->StopSynchronously();
346 logger->TearDownProfilerListener();
614 processor_.reset(); 347 processor_.reset();
615 generator_.reset(); 348 generator_.reset();
616 sampler->SetHasProcessingThread(false); 349 sampler->SetHasProcessingThread(false);
617 sampler->DecreaseProfilingDepth(); 350 sampler->DecreaseProfilingDepth();
618 logger->is_logging_ = saved_is_logging_; 351 logger->is_logging_ = saved_is_logging_;
619 } 352 }
620 353
621 354
622 void CpuProfiler::LogBuiltins() { 355 void CpuProfiler::LogBuiltins() {
623 Builtins* builtins = isolate_->builtins(); 356 Builtins* builtins = isolate_->builtins();
624 DCHECK(builtins->is_initialized()); 357 DCHECK(builtins->is_initialized());
625 for (int i = 0; i < Builtins::builtin_count; i++) { 358 for (int i = 0; i < Builtins::builtin_count; i++) {
626 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); 359 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
627 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; 360 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
628 Builtins::Name id = static_cast<Builtins::Name>(i); 361 Builtins::Name id = static_cast<Builtins::Name>(i);
629 rec->start = builtins->builtin(id)->address(); 362 rec->start = builtins->builtin(id)->address();
630 rec->builtin_id = id; 363 rec->builtin_id = id;
631 processor_->Enqueue(evt_rec); 364 processor_->Enqueue(evt_rec);
632 } 365 }
633 } 366 }
634 367
635
636 } // namespace internal 368 } // namespace internal
637 } // namespace v8 369 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698