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

Side by Side Diff: runtime/vm/profiler.cc

Issue 100103011: Changes to support dprof and Observatory profiler UIs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <cstdio>
6
7 #include "platform/utils.h" 5 #include "platform/utils.h"
8 6
7 #include "vm/allocation.h"
9 #include "vm/atomic.h" 8 #include "vm/atomic.h"
9 #include "vm/code_patcher.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
11 #include "vm/json_stream.h" 11 #include "vm/json_stream.h"
12 #include "vm/native_symbol.h" 12 #include "vm/native_symbol.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/os.h" 14 #include "vm/os.h"
15 #include "vm/profiler.h" 15 #include "vm/profiler.h"
16 #include "vm/signal_handler.h" 16 #include "vm/signal_handler.h"
17 #include "vm/simulator.h" 17 #include "vm/simulator.h"
18 18
19 namespace dart { 19 namespace dart {
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 if ((stack_lower == 0) || (stack_upper == 0)) { 211 if ((stack_lower == 0) || (stack_upper == 0)) {
212 stack_lower = 0; 212 stack_lower = 0;
213 stack_upper = 0; 213 stack_upper = 0;
214 } 214 }
215 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, 215 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
216 state.pc, state.fp, state.sp); 216 state.pc, state.fp, state.sp);
217 stackWalker.walk(); 217 stackWalker.walk();
218 } 218 }
219 219
220 220
221 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream) { 221 struct AddressEntry {
222 uintptr_t pc;
223 uintptr_t ticks;
224 };
225
226
227 // A region of code. Each region is a kind of code (Dart, Collected, or Native).
228 class CodeRegion : public ZoneAllocated {
229 public:
230 enum Kind {
231 kDartCode,
232 kCollectedCode,
233 kNativeCode
234 };
235
236 CodeRegion(Kind kind, uintptr_t start, uintptr_t end) :
237 kind_(kind),
238 start_(start),
239 end_(end),
240 inclusive_ticks_(0),
241 exclusive_ticks_(0),
242 name_(NULL),
243 address_table_(new ZoneGrowableArray<AddressEntry>()) {
244 }
245
246 ~CodeRegion() {
Ivan Posva 2014/01/03 19:24:54 ZoneAllocated and thus CodeRegion destructors are
Cutch 2014/01/03 19:42:30 Done.
247 if (name_ != NULL) {
248 free(const_cast<char*>(name_));
249 name_ = NULL;
250 }
251 }
252
253 uintptr_t start() const { return start_; }
254 void set_start(uintptr_t start) {
255 start_ = start;
256 }
257
258 uintptr_t end() const { return end_; }
259 void set_end(uintptr_t end) {
260 end_ = end;
261 }
262
263 void AdjustExtent(uintptr_t start, uintptr_t end) {
264 if (start < start_) {
265 start_ = start;
266 }
267 if (end > end_) {
268 end_ = end;
269 }
270 }
271
272 bool contains(uintptr_t pc) const {
273 return (pc >= start_) && (pc < end_);
274 }
275
276 intptr_t inclusive_ticks() const { return inclusive_ticks_; }
277 void set_inclusive_ticks(intptr_t inclusive_ticks) {
278 inclusive_ticks_ = inclusive_ticks;
279 }
280
281 intptr_t exclusive_ticks() const { return exclusive_ticks_; }
282 void set_exclusive_ticks(intptr_t exclusive_ticks) {
283 exclusive_ticks_ = exclusive_ticks;
284 }
285
286 const char* name() const { return name_; }
287 void SetName(const char* name) {
288 if (name == NULL) {
289 name_ = NULL;
290 }
291 intptr_t len = strlen(name);
292 name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
293 strncpy(const_cast<char*>(name_), name, len);
294 const_cast<char*>(name_)[len] = '\0';
295 }
296
297 Kind kind() const { return kind_; }
298
299 static const char* KindToCString(Kind kind) {
300 switch (kind) {
301 case kDartCode:
302 return "Dart";
303 case kCollectedCode:
304 return "Collected";
305 case kNativeCode:
306 return "Native";
307 }
308 UNREACHABLE();
309 return NULL;
310 }
311
312 void AddTick(bool exclusive) {
313 if (exclusive) {
314 exclusive_ticks_++;
315 } else {
316 inclusive_ticks_++;
317 }
318 }
319
320 void AddTickAtAddress(uintptr_t pc) {
321 const intptr_t length = address_table_->length();
322 intptr_t i = 0;
323 for (; i < length; i++) {
324 AddressEntry& entry = (*address_table_)[i];
325 if (entry.pc == pc) {
326 entry.ticks++;
327 return;
328 }
329 if (entry.pc > pc) {
330 break;
331 }
332 }
333 AddressEntry entry;
334 entry.pc = pc;
335 entry.ticks = 1;
336 if (i < length) {
337 // Insert at i.
338 address_table_->InsertAt(i, entry);
339 } else {
340 // Add to end.
341 address_table_->Add(entry);
342 }
343 }
344
345
346 void PrintToJSONArray(JSONArray* events, bool full) {
347 JSONObject obj(events);
348 obj.AddProperty("type", "ProfileCode");
349 obj.AddProperty("kind", KindToCString(kind()));
350 obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks());
351 obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks());
352 if (kind() == kDartCode) {
353 // Look up code in Dart heap.
354 Code& code = Code::Handle(Code::LookupCode(start()));
355 Function& func = Function::Handle();
356 ASSERT(!code.IsNull());
357 func ^= code.function();
358 if (func.IsNull()) {
359 if (name() == NULL) {
360 GenerateAndSetSymbolName("Stub");
361 }
362 obj.AddPropertyF("start", "%" Px "", start());
363 obj.AddPropertyF("end", "%" Px "", end());
364 obj.AddProperty("name", name());
365 } else {
366 obj.AddProperty("code", code, !full);
367 }
368 } else if (kind() == kCollectedCode) {
369 if (name() == NULL) {
370 GenerateAndSetSymbolName("Collected");
371 }
372 obj.AddPropertyF("start", "%" Px "", start());
373 obj.AddPropertyF("end", "%" Px "", end());
374 obj.AddProperty("name", name());
375 } else {
376 ASSERT(kind() == kNativeCode);
377 if (name() == NULL) {
378 GenerateAndSetSymbolName("Native");
379 }
380 obj.AddPropertyF("start", "%" Px "", start());
381 obj.AddPropertyF("end", "%" Px "", end());
382 obj.AddProperty("name", name());
383 }
384 {
385 JSONArray ticks(&obj, "ticks");
386 for (intptr_t i = 0; i < address_table_->length(); i++) {
387 const AddressEntry& entry = (*address_table_)[i];
388 ticks.AddValueF("%" Px "", entry.pc);
389 ticks.AddValueF("%" Pd "", entry.ticks);
390 }
391 }
392 }
393
394 private:
395 void GenerateAndSetSymbolName(const char* prefix) {
396 const intptr_t kBuffSize = 512;
397 char buff[kBuffSize];
398 OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
399 prefix, start(), end());
400 SetName(buff);
401 }
402
403 Kind kind_;
404 uintptr_t start_;
405 uintptr_t end_;
406 intptr_t inclusive_ticks_;
407 intptr_t exclusive_ticks_;
408 const char* name_;
409 ZoneGrowableArray<AddressEntry>* address_table_;
410
411 DISALLOW_COPY_AND_ASSIGN(CodeRegion);
412 };
413
414
415 // All code regions. Code region tables are built on demand when a profile
416 // is requested (through the service or on isolate shutdown).
417 class ProfilerCodeRegionTable : public ValueObject {
418 public:
419 explicit ProfilerCodeRegionTable(Isolate* isolate) :
420 heap_(isolate->heap()),
421 code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) {
422 }
423
424 ~ProfilerCodeRegionTable() {
425 }
426
427 void AddTick(uintptr_t pc, bool exclusive) {
428 intptr_t index = FindIndex(pc);
429 if (index < 0) {
430 CodeRegion* code_region = CreateCodeRegion(pc);
431 ASSERT(code_region != NULL);
432 index = InsertCodeRegion(code_region);
433 }
434 ASSERT(index >= 0);
435 ASSERT(index < code_region_table_->length());
436 (*code_region_table_)[index]->AddTick(exclusive);
437 (*code_region_table_)[index]->AddTickAtAddress(pc);
Ivan Posva 2014/01/03 19:24:54 This will distort the exclusive ticks with too man
Cutch 2014/01/03 19:42:30 Good catch. Fixed by conditionally ticking the add
438 }
439
440 intptr_t Length() const { return code_region_table_->length(); }
441
442 CodeRegion* At(intptr_t idx) {
443 return (*code_region_table_)[idx];
444 }
445
446 private:
447 intptr_t FindIndex(uintptr_t pc) {
448 const intptr_t length = code_region_table_->length();
449 for (intptr_t i = 0; i < length; i++) {
450 const CodeRegion* code_region = (*code_region_table_)[i];
451 if (code_region->contains(pc)) {
452 return i;
453 }
454 }
455 return -1;
456 }
457
458 CodeRegion* CreateCodeRegion(uintptr_t pc) {
459 Code& code = Code::Handle(Code::LookupCode(pc));
460 if (!code.IsNull()) {
461 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(),
462 code.EntryPoint() + code.Size());
463 }
464 if (heap_->CodeContains(pc)) {
465 const intptr_t kDartCodeAlignment = 0x10;
466 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
467 return new CodeRegion(CodeRegion::kCollectedCode,
468 (pc & kDartCodeAlignmentMask),
469 (pc & kDartCodeAlignmentMask) + kDartCodeAlignment);
470 }
471 uintptr_t native_start = 0;
472 char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
473 &native_start);
474 if (native_name == NULL) {
475 return new CodeRegion(CodeRegion::kNativeCode, pc, pc + 1);
476 }
477 ASSERT(pc >= native_start);
478 CodeRegion* code_region =
479 new CodeRegion(CodeRegion::kNativeCode, native_start, pc + 1);
480 code_region->SetName(native_name);
481 free(native_name);
482 return code_region;
483 }
484
485 intptr_t InsertCodeRegion(CodeRegion* code_region) {
486 const intptr_t length = code_region_table_->length();
487 const uintptr_t start = code_region->start();
488 const uintptr_t end = code_region->end();
489 intptr_t i = 0;
490 for (; i < length; i++) {
491 CodeRegion* region = (*code_region_table_)[i];
492 if (region->contains(start) || region->contains(end - 1)) {
493 // We should only see overlapping native code regions.
494 ASSERT(region->kind() == CodeRegion::kNativeCode);
495 // When code regions overlap, they should be of the same kind.
496 ASSERT(region->kind() == code_region->kind());
497 // Overlapping code region.
498 region->AdjustExtent(start, end);
499 return i;
500 } else if (start >= region->end()) {
501 // Insert here.
502 break;
503 }
504 }
505 if (i != length) {
506 code_region_table_->InsertAt(i, code_region);
507 return i;
508 }
509 code_region_table_->Add(code_region);
510 return code_region_table_->length() - 1;
511 }
512
513 Heap* heap_;
514 ZoneGrowableArray<CodeRegion*>* code_region_table_;
515 };
516
517
518 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream,
519 bool full) {
222 ASSERT(isolate == Isolate::Current()); 520 ASSERT(isolate == Isolate::Current());
223 UNIMPLEMENTED(); 521 // Disable profile interrupts while processing the buffer.
522 EndExecution(isolate);
523 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
524 IsolateProfilerData* profiler_data = isolate->profiler_data();
525 if (profiler_data == NULL) {
526 JSONObject error(stream);
527 error.AddProperty("type", "Error");
528 error.AddProperty("text", "Isolate does not have profiling enabled.");
529 return;
530 }
531 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
532 ASSERT(sample_buffer != NULL);
533 {
534 StackZone zone(isolate);
535 {
536 // Build code region table.
537 ProfilerCodeRegionTable code_region_table(isolate);
538 intptr_t samples =
539 ProcessSamples(isolate, &code_region_table, sample_buffer);
540 {
541 // Serialize to JSON.
542 JSONObject obj(stream);
543 obj.AddProperty("type", "Profile");
544 obj.AddProperty("samples", samples);
545 JSONArray codes(&obj, "codes");
546 for (intptr_t i = 0; i < code_region_table.Length(); i++) {
547 CodeRegion* region = code_region_table.At(i);
548 ASSERT(region != NULL);
549 region->PrintToJSONArray(&codes, full);
550 }
551 }
552 }
553 }
554 // Enable profile interrupts.
555 BeginExecution(isolate);
224 } 556 }
225 557
226 558
227 static const char* FindSymbolName(uintptr_t pc, bool* symbol_name_allocated) { 559 intptr_t Profiler::ProcessSamples(Isolate* isolate,
228 // TODO(johnmccutchan): Differentiate between symbols which can't be found 560 ProfilerCodeRegionTable* code_region_table,
229 // and symbols which were GCed. (Heap::CodeContains). 561 SampleBuffer* sample_buffer) {
230 ASSERT(symbol_name_allocated != NULL); 562 int64_t start = OS::GetCurrentTimeMillis();
231 const char* symbol_name = "Unknown"; 563 intptr_t samples = 0;
232 *symbol_name_allocated = false; 564 for (intptr_t i = 0; i < sample_buffer->capacity(); i++) {
233 if (pc == 0) { 565 Sample sample = sample_buffer->GetSample(i);
234 return const_cast<char*>(Sample::kNoFrame); 566 if (sample.isolate != isolate) {
235 } 567 continue;
236 const Code& code = Code::Handle(Code::LookupCode(pc)); 568 }
237 if (!code.IsNull()) { 569 if (sample.timestamp == 0) {
238 const Function& function = Function::Handle(code.function()); 570 continue;
239 if (!function.IsNull()) { 571 }
240 const String& name = String::Handle(function.QualifiedUserVisibleName()); 572 samples += ProcessSample(isolate, code_region_table, &sample);
241 if (!name.IsNull()) { 573 }
242 symbol_name = name.ToCString(); 574 int64_t end = OS::GetCurrentTimeMillis();
243 return symbol_name; 575 if (FLAG_trace_profiled_isolates) {
244 } 576 int64_t delta = end - start;
245 } 577 OS::Print("Processed %" Pd " samples from %s in %" Pd64 " milliseconds.\n",
246 } else { 578 samples,
247 // Possibly a native symbol. 579 isolate->name(),
248 char* native_name = NativeSymbolResolver::LookupSymbolName(pc); 580 delta);
249 if (native_name != NULL) { 581 }
250 symbol_name = native_name; 582 return samples;
251 *symbol_name_allocated = true;
252 return symbol_name;
253 }
254 }
255 const intptr_t kBucketSize = 256;
256 const intptr_t kBucketMask = ~(kBucketSize - 1);
257 // Not a Dart symbol or a native symbol. Bin into buckets by PC.
258 pc &= kBucketMask;
259 {
260 const intptr_t kBuffSize = 256;
261 char buff[kBuffSize];
262 OS::SNPrint(&buff[0], kBuffSize-1, "Unknown [%" Px ", %" Px ")",
263 pc, pc + kBucketSize);
264 symbol_name = strdup(buff);
265 *symbol_name_allocated = true;
266 }
267 return symbol_name;
268 } 583 }
269 584
270 585
271 void Profiler::WriteTracingSample(Isolate* isolate, intptr_t pid, 586 intptr_t Profiler::ProcessSample(Isolate* isolate,
272 Sample* sample, JSONArray& events) { 587 ProfilerCodeRegionTable* code_region_table,
588 Sample* sample) {
273 Sample::SampleType type = sample->type; 589 Sample::SampleType type = sample->type;
274 intptr_t tid = Thread::ThreadIdToIntPtr(sample->tid); 590 if (type != Sample::kIsolateSample) {
275 double timestamp = static_cast<double>(sample->timestamp); 591 return 0;
276 const char* isolate_name = isolate->name(); 592 }
277 switch (type) { 593 if (sample->pcs[0] == 0) {
278 case Sample::kIsolateStart: { 594 // No frames in this sample.
279 JSONObject begin(&events); 595 return 0;
280 begin.AddProperty("ph", "B"); 596 }
281 begin.AddProperty("tid", tid); 597 intptr_t i = 0;
282 begin.AddProperty("pid", pid); 598 // i points to the leaf (exclusive) PC sample.
283 begin.AddProperty("name", isolate_name); 599 code_region_table->AddTick(sample->pcs[i], true);
284 begin.AddProperty("ts", timestamp); 600 for (; i < Sample::kNumStackFrames; i++) {
285 } 601 if (sample->pcs[i] == 0) {
286 break; 602 break;
287 case Sample::kIsolateStop: { 603 }
288 JSONObject begin(&events); 604 code_region_table->AddTick(sample->pcs[i], false);
Ivan Posva 2014/01/03 19:24:54 Double counting the exclusive ticks as inclusive t
Cutch 2014/01/03 19:42:30 Giving all code regions an inclusive tick was int
289 begin.AddProperty("ph", "E"); 605 }
290 begin.AddProperty("tid", tid); 606 return 1;
291 begin.AddProperty("pid", pid);
292 begin.AddProperty("name", isolate_name);
293 begin.AddProperty("ts", timestamp);
294 }
295 break;
296 case Sample::kIsolateSample:
297 // Write "B" events.
298 for (int i = Sample::kNumStackFrames - 1; i >= 0; i--) {
299 bool symbol_name_allocated = false;
300 const char* symbol_name = FindSymbolName(sample->pcs[i],
301 &symbol_name_allocated);
302 {
303 JSONObject begin(&events);
304 begin.AddProperty("ph", "B");
305 begin.AddProperty("tid", tid);
306 begin.AddProperty("pid", pid);
307 begin.AddProperty("name", symbol_name);
308 begin.AddProperty("ts", timestamp);
309 }
310 if (symbol_name_allocated) {
311 free(const_cast<char*>(symbol_name));
312 }
313 }
314 // Write "E" events.
315 for (int i = 0; i < Sample::kNumStackFrames; i++) {
316 bool symbol_name_allocated = false;
317 const char* symbol_name = FindSymbolName(sample->pcs[i],
318 &symbol_name_allocated);
319 {
320 JSONObject begin(&events);
321 begin.AddProperty("ph", "E");
322 begin.AddProperty("tid", tid);
323 begin.AddProperty("pid", pid);
324 begin.AddProperty("name", symbol_name);
325 begin.AddProperty("ts", timestamp);
326 }
327 if (symbol_name_allocated) {
328 free(const_cast<char*>(symbol_name));
329 }
330 }
331 break;
332 default:
333 UNIMPLEMENTED();
334 }
335 } 607 }
336 608
337 609
338 void Profiler::WriteTracing(Isolate* isolate) { 610 void Profiler::WriteProfile(Isolate* isolate) {
339 if (isolate == NULL) { 611 if (isolate == NULL) {
340 return; 612 return;
341 } 613 }
342 if (!FLAG_profile) { 614 if (!FLAG_profile) {
343 return; 615 return;
344 } 616 }
345 ASSERT(initialized_); 617 ASSERT(initialized_);
346 if (FLAG_profile_dir == NULL) { 618 if (FLAG_profile_dir == NULL) {
347 return; 619 return;
348 } 620 }
349 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); 621 Dart_FileOpenCallback file_open = Isolate::file_open_callback();
350 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); 622 Dart_FileCloseCallback file_close = Isolate::file_close_callback();
351 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); 623 Dart_FileWriteCallback file_write = Isolate::file_write_callback();
352 if ((file_open == NULL) || (file_close == NULL) || (file_write == NULL)) { 624 if ((file_open == NULL) || (file_close == NULL) || (file_write == NULL)) {
353 // Embedder has not provided necessary callbacks. 625 // Embedder has not provided necessary callbacks.
354 return; 626 return;
355 } 627 }
356 // We will be looking up code objects within the isolate. 628 // We will be looking up code objects within the isolate.
357 ASSERT(Isolate::Current() != NULL); 629 ASSERT(Isolate::Current() == isolate);
358 // We do not want to be interrupted while processing the buffer.
359 EndExecution(isolate);
360 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
361 IsolateProfilerData* profiler_data = isolate->profiler_data();
362 if (profiler_data == NULL) {
363 return;
364 }
365 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
366 ASSERT(sample_buffer != NULL);
367 JSONStream stream(10 * MB); 630 JSONStream stream(10 * MB);
368 intptr_t pid = OS::ProcessId(); 631 intptr_t pid = OS::ProcessId();
369 { 632 PrintToJSONStream(isolate, &stream, true);
370 JSONArray events(&stream);
371 {
372 JSONObject process_name(&events);
373 process_name.AddProperty("name", "process_name");
374 process_name.AddProperty("ph", "M");
375 process_name.AddProperty("pid", pid);
376 {
377 JSONObject args(&process_name, "args");
378 args.AddProperty("name", "Dart VM");
379 }
380 }
381 for (intptr_t i = 0; i < sample_buffer->capacity(); i++) {
382 Sample* sample = sample_buffer->GetSample(i);
383 if (sample->isolate != isolate) {
384 continue;
385 }
386 if (sample->timestamp == 0) {
387 continue;
388 }
389 WriteTracingSample(isolate, pid, sample, events);
390 }
391 }
392 const char* format = "%s/dart-profile-%" Pd "-%" Pd ".json"; 633 const char* format = "%s/dart-profile-%" Pd "-%" Pd ".json";
393 intptr_t len = OS::SNPrint(NULL, 0, format, 634 intptr_t len = OS::SNPrint(NULL, 0, format,
394 FLAG_profile_dir, pid, isolate->main_port()); 635 FLAG_profile_dir, pid, isolate->main_port());
395 char* filename = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 636 char* filename = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
396 OS::SNPrint(filename, len + 1, format, 637 OS::SNPrint(filename, len + 1, format,
397 FLAG_profile_dir, pid, isolate->main_port()); 638 FLAG_profile_dir, pid, isolate->main_port());
398 void* f = file_open(filename, true); 639 void* f = file_open(filename, true);
399 if (f == NULL) { 640 if (f == NULL) {
400 // Cannot write. 641 // Cannot write.
401 return; 642 return;
402 } 643 }
403 TextBuffer* buffer = stream.buffer(); 644 TextBuffer* buffer = stream.buffer();
404 ASSERT(buffer != NULL); 645 ASSERT(buffer != NULL);
405 file_write(buffer->buf(), buffer->length(), f); 646 file_write(buffer->buf(), buffer->length(), f);
406 file_close(f); 647 file_close(f);
407 BeginExecution(isolate);
408 } 648 }
409 649
410 650
411 IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer, 651 IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
412 bool own_sample_buffer) { 652 bool own_sample_buffer) {
413 sample_buffer_ = sample_buffer; 653 sample_buffer_ = sample_buffer;
414 own_sample_buffer_ = own_sample_buffer; 654 own_sample_buffer_ = own_sample_buffer;
415 } 655 }
416 656
417 657
418 IsolateProfilerData::~IsolateProfilerData() { 658 IsolateProfilerData::~IsolateProfilerData() {
419 if (own_sample_buffer_) { 659 if (own_sample_buffer_) {
420 delete sample_buffer_; 660 delete sample_buffer_;
421 sample_buffer_ = NULL; 661 sample_buffer_ = NULL;
422 own_sample_buffer_ = false; 662 own_sample_buffer_ = false;
423 } 663 }
424 } 664 }
425 665
426 666
427 const char* Sample::kLookupSymbol = "Symbol Not Looked Up";
428 const char* Sample::kNoSymbol = "No Symbol Found";
429 const char* Sample::kNoFrame = "<no frame>";
430
431 void Sample::Init(SampleType type, Isolate* isolate, int64_t timestamp, 667 void Sample::Init(SampleType type, Isolate* isolate, int64_t timestamp,
432 ThreadId tid) { 668 ThreadId tid) {
433 this->timestamp = timestamp; 669 this->timestamp = timestamp;
434 this->tid = tid; 670 this->tid = tid;
435 this->isolate = isolate; 671 this->isolate = isolate;
436 for (intptr_t i = 0; i < kNumStackFrames; i++) { 672 for (intptr_t i = 0; i < kNumStackFrames; i++) {
437 pcs[i] = 0; 673 pcs[i] = 0;
438 } 674 }
439 this->type = type; 675 this->type = type;
440 vm_tags = 0; 676 vm_tags = 0;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 return false; 786 return false;
551 } 787 }
552 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); 788 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp);
553 cursor += sizeof(fp); 789 cursor += sizeof(fp);
554 bool r = cursor >= lower_bound_ && cursor < stack_upper_; 790 bool r = cursor >= lower_bound_ && cursor < stack_upper_;
555 return r; 791 return r;
556 } 792 }
557 793
558 794
559 } // namespace dart 795 } // namespace dart
OLDNEW
« runtime/vm/profiler.h ('K') | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698