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

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

Powered by Google App Engine
This is Rietveld 408576698