| 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 |