OLD | NEW |
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 "platform/utils.h" | 5 #include "platform/utils.h" |
6 | 6 |
7 #include "vm/allocation.h" | 7 #include "vm/allocation.h" |
8 #include "vm/atomic.h" | 8 #include "vm/atomic.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 } | 322 } |
323 | 323 |
324 void AddCaller(intptr_t index) { | 324 void AddCaller(intptr_t index) { |
325 AddCallEntry(callers_table_, index); | 325 AddCallEntry(callers_table_, index); |
326 } | 326 } |
327 | 327 |
328 void AddCallee(intptr_t index) { | 328 void AddCallee(intptr_t index) { |
329 AddCallEntry(callees_table_, index); | 329 AddCallEntry(callees_table_, index); |
330 } | 330 } |
331 | 331 |
332 void PrintToJSONArray(JSONArray* events, bool full) { | 332 void PrintNativeCode(JSONObject* profile_code_obj) { |
| 333 ASSERT(kind() == kNativeCode); |
| 334 JSONObject obj(profile_code_obj, "code"); |
| 335 obj.AddProperty("type", "@Code"); |
| 336 obj.AddProperty("kind", "Native"); |
| 337 obj.AddProperty("name", name()); |
| 338 obj.AddProperty("user_name", name()); |
| 339 obj.AddPropertyF("start", "%" Px "", start()); |
| 340 obj.AddPropertyF("end", "%" Px "", end()); |
| 341 obj.AddPropertyF("id", "code/native/%" Px "", start()); |
| 342 } |
| 343 |
| 344 void PrintCollectedCode(JSONObject* profile_code_obj) { |
| 345 ASSERT(kind() == kCollectedCode); |
| 346 JSONObject obj(profile_code_obj, "code"); |
| 347 obj.AddProperty("type", "@Code"); |
| 348 obj.AddProperty("kind", "Collected"); |
| 349 obj.AddProperty("name", name()); |
| 350 obj.AddProperty("user_name", name()); |
| 351 obj.AddPropertyF("start", "%" Px "", start()); |
| 352 obj.AddPropertyF("end", "%" Px "", end()); |
| 353 obj.AddPropertyF("id", "code/collected/%" Px "", start()); |
| 354 } |
| 355 |
| 356 void PrintToJSONArray(Isolate* isolate, JSONArray* events, bool full) { |
333 JSONObject obj(events); | 357 JSONObject obj(events); |
334 obj.AddProperty("type", "ProfileCode"); | 358 obj.AddProperty("type", "ProfileCode"); |
335 obj.AddProperty("kind", KindToCString(kind())); | 359 obj.AddProperty("kind", KindToCString(kind())); |
336 obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks()); | 360 obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks()); |
337 obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks()); | 361 obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks()); |
338 if (kind() == kDartCode) { | 362 if (kind() == kDartCode) { |
339 // Look up code in Dart heap. | 363 // Look up code in Dart heap. |
340 Code& code = Code::Handle(Code::LookupCode(start())); | 364 Code& code = Code::Handle(); |
341 Function& func = Function::Handle(); | 365 code ^= Code::LookupCode(start()); |
| 366 if (code.IsNull()) { |
| 367 // Code is a stub in the Vm isolate. |
| 368 code ^= Code::LookupCodeInVmIsolate(start()); |
| 369 } |
342 ASSERT(!code.IsNull()); | 370 ASSERT(!code.IsNull()); |
343 func ^= code.function(); | 371 obj.AddProperty("code", code, !full); |
344 if (func.IsNull()) { | |
345 if (name() == NULL) { | |
346 const char* stub_name = StubCode::NameOfStub(start()); | |
347 GenerateAndSetSymbolName(stub_name == NULL ? "Stub" : stub_name); | |
348 } | |
349 obj.AddPropertyF("start", "%" Px "", start()); | |
350 obj.AddPropertyF("end", "%" Px "", end()); | |
351 obj.AddProperty("name", name()); | |
352 } else { | |
353 obj.AddProperty("code", code, !full); | |
354 } | |
355 } else if (kind() == kCollectedCode) { | 372 } else if (kind() == kCollectedCode) { |
356 if (name() == NULL) { | 373 if (name() == NULL) { |
| 374 // Lazily set generated name. |
357 GenerateAndSetSymbolName("Collected"); | 375 GenerateAndSetSymbolName("Collected"); |
358 } | 376 } |
359 obj.AddPropertyF("start", "%" Px "", start()); | 377 PrintCollectedCode(&obj); |
360 obj.AddPropertyF("end", "%" Px "", end()); | |
361 obj.AddProperty("name", name()); | |
362 } else { | 378 } else { |
363 ASSERT(kind() == kNativeCode); | 379 ASSERT(kind() == kNativeCode); |
364 if (name() == NULL) { | 380 if (name() == NULL) { |
| 381 // Lazily set generated name. |
365 GenerateAndSetSymbolName("Native"); | 382 GenerateAndSetSymbolName("Native"); |
366 } | 383 } |
367 obj.AddPropertyF("start", "%" Px "", start()); | 384 PrintNativeCode(&obj); |
368 obj.AddPropertyF("end", "%" Px "", end()); | |
369 obj.AddProperty("name", name()); | |
370 } | 385 } |
371 { | 386 { |
372 JSONArray ticks(&obj, "ticks"); | 387 JSONArray ticks(&obj, "ticks"); |
373 for (intptr_t i = 0; i < address_table_->length(); i++) { | 388 for (intptr_t i = 0; i < address_table_->length(); i++) { |
374 const AddressEntry& entry = (*address_table_)[i]; | 389 const AddressEntry& entry = (*address_table_)[i]; |
375 ticks.AddValueF("%" Px "", entry.pc); | 390 ticks.AddValueF("%" Px "", entry.pc); |
376 ticks.AddValueF("%" Pd "", entry.exclusive_ticks); | 391 ticks.AddValueF("%" Pd "", entry.exclusive_ticks); |
377 ticks.AddValueF("%" Pd "", entry.inclusive_ticks); | 392 ticks.AddValueF("%" Pd "", entry.inclusive_ticks); |
378 } | 393 } |
379 } | 394 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 | 557 |
543 static bool CompareUpperBound(uword pc, uword start, uword end) { | 558 static bool CompareUpperBound(uword pc, uword start, uword end) { |
544 return pc >= end; | 559 return pc >= end; |
545 } | 560 } |
546 | 561 |
547 static bool CompareLowerBound(uword pc, uword start, uword end) { | 562 static bool CompareLowerBound(uword pc, uword start, uword end) { |
548 return end <= pc; | 563 return end <= pc; |
549 } | 564 } |
550 | 565 |
551 CodeRegion* CreateCodeRegion(uword pc) { | 566 CodeRegion* CreateCodeRegion(uword pc) { |
552 Code& code = Code::Handle(Code::LookupCode(pc)); | 567 Code& code = Code::Handle(); |
| 568 code ^= Code::LookupCode(pc); |
| 569 if (!code.IsNull()) { |
| 570 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(), |
| 571 code.EntryPoint() + code.Size()); |
| 572 } |
| 573 code ^= Code::LookupCodeInVmIsolate(pc); |
553 if (!code.IsNull()) { | 574 if (!code.IsNull()) { |
554 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(), | 575 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(), |
555 code.EntryPoint() + code.Size()); | 576 code.EntryPoint() + code.Size()); |
556 } | 577 } |
557 if (heap_->CodeContains(pc)) { | 578 if (heap_->CodeContains(pc)) { |
558 const intptr_t kDartCodeAlignment = 0x10; | 579 const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment(); |
559 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1); | 580 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1); |
560 return new CodeRegion(CodeRegion::kCollectedCode, pc, | 581 return new CodeRegion(CodeRegion::kCollectedCode, pc, |
561 (pc & kDartCodeAlignmentMask) + kDartCodeAlignment); | 582 (pc & kDartCodeAlignmentMask) + kDartCodeAlignment); |
562 } | 583 } |
563 uintptr_t native_start = 0; | 584 uintptr_t native_start = 0; |
564 char* native_name = NativeSymbolResolver::LookupSymbolName(pc, | 585 char* native_name = NativeSymbolResolver::LookupSymbolName(pc, |
565 &native_start); | 586 &native_start); |
566 if (native_name == NULL) { | 587 if (native_name == NULL) { |
567 return new CodeRegion(CodeRegion::kNativeCode, pc, pc + 1); | 588 return new CodeRegion(CodeRegion::kNativeCode, pc, pc + 1); |
568 } | 589 } |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 { | 804 { |
784 ScopeStopwatch sw("CodeTableStream"); | 805 ScopeStopwatch sw("CodeTableStream"); |
785 // Serialize to JSON. | 806 // Serialize to JSON. |
786 JSONObject obj(stream); | 807 JSONObject obj(stream); |
787 obj.AddProperty("type", "Profile"); | 808 obj.AddProperty("type", "Profile"); |
788 obj.AddProperty("samples", samples); | 809 obj.AddProperty("samples", samples); |
789 JSONArray codes(&obj, "codes"); | 810 JSONArray codes(&obj, "codes"); |
790 for (intptr_t i = 0; i < code_region_table.Length(); i++) { | 811 for (intptr_t i = 0; i < code_region_table.Length(); i++) { |
791 CodeRegion* region = code_region_table.At(i); | 812 CodeRegion* region = code_region_table.At(i); |
792 ASSERT(region != NULL); | 813 ASSERT(region != NULL); |
793 region->PrintToJSONArray(&codes, full); | 814 region->PrintToJSONArray(isolate, &codes, full); |
794 } | 815 } |
795 } | 816 } |
796 } | 817 } |
797 } | 818 } |
798 // Enable profile interrupts. | 819 // Enable profile interrupts. |
799 BeginExecution(isolate); | 820 BeginExecution(isolate); |
800 } | 821 } |
801 | 822 |
802 | 823 |
803 void Profiler::WriteProfile(Isolate* isolate) { | 824 void Profiler::WriteProfile(Isolate* isolate) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 stack_lower = 0; | 1032 stack_lower = 0; |
1012 stack_upper = 0; | 1033 stack_upper = 0; |
1013 } | 1034 } |
1014 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, | 1035 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, |
1015 state.pc, state.fp, state.sp); | 1036 state.pc, state.fp, state.sp); |
1016 stackWalker.walk(isolate->heap()); | 1037 stackWalker.walk(isolate->heap()); |
1017 } | 1038 } |
1018 | 1039 |
1019 | 1040 |
1020 } // namespace dart | 1041 } // namespace dart |
OLD | NEW |