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

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

Issue 1779333004: Add profile data to getSourceReport (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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 | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.cc » ('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 (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 "vm/profiler_service.h" 5 #include "vm/profiler_service.h"
6 6
7 #include "vm/growable_array.h" 7 #include "vm/growable_array.h"
8 #include "vm/log.h" 8 #include "vm/log.h"
9 #include "vm/native_symbol.h" 9 #include "vm/native_symbol.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 return; 150 return;
151 } 151 }
152 inclusive_serial_ = inclusive_serial; 152 inclusive_serial_ = inclusive_serial;
153 inclusive_ticks_++; 153 inclusive_ticks_++;
154 TickSourcePosition(token_position, false); 154 TickSourcePosition(token_position, false);
155 } 155 }
156 156
157 157
158 void ProfileFunction::TickSourcePosition(TokenPosition token_position, 158 void ProfileFunction::TickSourcePosition(TokenPosition token_position,
159 bool exclusive) { 159 bool exclusive) {
160 for (intptr_t i = 0; i < source_position_ticks_.length(); i++) { 160 intptr_t i = 0;
161 for (; i < source_position_ticks_.length(); i++) {
161 ProfileFunctionSourcePosition& position = source_position_ticks_[i]; 162 ProfileFunctionSourcePosition& position = source_position_ticks_[i];
162 if (position.token_pos() == token_position) { 163 if (position.token_pos().value() == token_position.value()) {
164 if (FLAG_trace_profiler) {
165 OS::Print("Ticking source position %s %s\n",
166 exclusive ? "exclusive" : "inclusive",
167 token_position.ToCString());
168 }
163 // Found existing position, tick it. 169 // Found existing position, tick it.
164 position.Tick(exclusive); 170 position.Tick(exclusive);
165 return; 171 return;
166 } 172 }
173 if (position.token_pos().value() > token_position.value()) {
174 break;
175 }
167 } 176 }
168 // Add new one. 177
178 // Add new one, sorted by token position value.
169 ProfileFunctionSourcePosition pfsp(token_position); 179 ProfileFunctionSourcePosition pfsp(token_position);
180 if (FLAG_trace_profiler) {
181 OS::Print("Ticking source position %s %s\n",
182 exclusive ? "exclusive" : "inclusive",
183 token_position.ToCString());
184 }
170 pfsp.Tick(exclusive); 185 pfsp.Tick(exclusive);
171 source_position_ticks_.Add(pfsp); 186
187 if (i < source_position_ticks_.length()) {
188 source_position_ticks_.InsertAt(i, pfsp);
189 } else {
190 source_position_ticks_.Add(pfsp);
191 }
172 } 192 }
173 193
174 194
175 const char* ProfileFunction::KindToCString(Kind kind) { 195 const char* ProfileFunction::KindToCString(Kind kind) {
176 switch (kind) { 196 switch (kind) {
177 case kDartFunction: 197 case kDartFunction:
178 return "Dart"; 198 return "Dart";
179 case kNativeFunction: 199 case kNativeFunction:
180 return "Native"; 200 return "Native";
181 case kTagFunction: 201 case kTagFunction:
(...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 } 1440 }
1421 1441
1422 // Truncated tag. 1442 // Truncated tag.
1423 if (sample->truncated()) { 1443 if (sample->truncated()) {
1424 current = AppendTruncatedTag(current); 1444 current = AppendTruncatedTag(current);
1425 InclusiveTickTruncatedTag(); 1445 InclusiveTickTruncatedTag();
1426 } 1446 }
1427 } 1447 }
1428 } 1448 }
1429 1449
1450 intptr_t OffsetForPC(uword pc,
1451 const Code& code,
1452 ProcessedSample* sample,
1453 intptr_t frame_index) {
1454 intptr_t offset = pc - code.EntryPoint();
1455 if (frame_index != 0) {
1456 // The PC of frames below the top frame is a call's return address,
1457 // which can belong to a different inlining interval than the call.
1458 offset--;
1459 } else if (sample->IsAllocationSample()) {
1460 // Allocation samples skip the top frame, so the top frame's pc is
1461 // also a call's return address.
1462 offset--;
1463 } else if (!sample->first_frame_executing()) {
1464 // If the first frame wasn't executing code (i.e. we started to collect
1465 // the stack trace at an exit frame), the top frame's pc is also a
1466 // call's return address.
1467 offset--;
1468 }
1469 return offset;
1470 }
1471
1430 ProfileFunctionTrieNode* ProcessFrame( 1472 ProfileFunctionTrieNode* ProcessFrame(
1431 ProfileFunctionTrieNode* current, 1473 ProfileFunctionTrieNode* current,
1432 intptr_t sample_index, 1474 intptr_t sample_index,
1433 ProcessedSample* sample, 1475 ProcessedSample* sample,
1434 intptr_t frame_index) { 1476 intptr_t frame_index) {
1435 const uword pc = sample->At(frame_index); 1477 const uword pc = sample->At(frame_index);
1436 ProfileCode* profile_code = GetProfileCode(pc, 1478 ProfileCode* profile_code = GetProfileCode(pc,
1437 sample->timestamp()); 1479 sample->timestamp());
1438 ProfileFunction* function = profile_code->function(); 1480 ProfileFunction* function = profile_code->function();
1439 ASSERT(function != NULL); 1481 ASSERT(function != NULL);
1440 const intptr_t code_index = profile_code->code_table_index(); 1482 const intptr_t code_index = profile_code->code_table_index();
1441 ASSERT(profile_code != NULL); 1483 ASSERT(profile_code != NULL);
1442 const Code& code = Code::ZoneHandle(profile_code->code()); 1484 const Code& code = Code::ZoneHandle(profile_code->code());
1443 GrowableArray<Function*> inlined_functions; 1485 GrowableArray<Function*> inlined_functions;
1444 GrowableArray<TokenPosition> inlined_token_positions; 1486 GrowableArray<TokenPosition> inlined_token_positions;
1445 TokenPosition token_position = TokenPosition::kNoSource; 1487 TokenPosition token_position = TokenPosition::kNoSource;
1446 if (!code.IsNull()) { 1488 if (!code.IsNull()) {
1447 intptr_t offset = pc - code.EntryPoint(); 1489 const intptr_t offset = OffsetForPC(pc, code, sample, frame_index);
1448 if (frame_index != 0) {
1449 // The PC of frames below the top frame is a call's return address,
1450 // which can belong to a different inlining interval than the call.
1451 offset--;
1452 } else if (sample->IsAllocationSample()) {
1453 // Allocation samples skip the top frame, so the top frame's pc is
1454 // also a call's return address.
1455 offset--;
1456 } else if (!sample->first_frame_executing()) {
1457 // If the first frame wasn't executing code (i.e. we started to collect
1458 // the stack trace at an exit frame), the top frame's pc is also a
1459 // call's return address.
1460 offset--;
1461 }
1462 code.GetInlinedFunctionsAt(offset, 1490 code.GetInlinedFunctionsAt(offset,
1463 &inlined_functions, 1491 &inlined_functions,
1464 &inlined_token_positions); 1492 &inlined_token_positions);
1465 token_position = code.GetTokenPositionAt(offset); 1493 token_position = code.GetTokenPositionAt(offset);
1466 if (inlined_functions.length() > 0) { 1494 if (inlined_functions.length() > 0) {
1467 // The inlined token position table does not include the token position 1495 // The inlined token position table does not include the token position
1468 // of the final call. Insert it at the beginning because the table. 1496 // of the final call. Insert it at the beginning because the table.
1469 // is reversed. 1497 // is reversed.
1470 inlined_token_positions.InsertAt(0, token_position); 1498 inlined_token_positions.InsertAt(0, token_position);
1471 } 1499 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 return IsExecutingFrame(sample, frame_index) || vm_tags_emitted(); 1608 return IsExecutingFrame(sample, frame_index) || vm_tags_emitted();
1581 } 1609 }
1582 1610
1583 ProfileFunctionTrieNode* ProcessFunction(ProfileFunctionTrieNode* current, 1611 ProfileFunctionTrieNode* ProcessFunction(ProfileFunctionTrieNode* current,
1584 intptr_t sample_index, 1612 intptr_t sample_index,
1585 ProcessedSample* sample, 1613 ProcessedSample* sample,
1586 intptr_t frame_index, 1614 intptr_t frame_index,
1587 ProfileFunction* function, 1615 ProfileFunction* function,
1588 TokenPosition token_position, 1616 TokenPosition token_position,
1589 intptr_t code_index) { 1617 intptr_t code_index) {
1590 if (FLAG_trace_profiler) {
1591 THR_Print("S[%" Pd "]F[%" Pd "] %s %s\n",
1592 sample_index,
1593 frame_index,
1594 function->Name(), token_position.ToCString());
1595 }
1596 if (tick_functions_) { 1618 if (tick_functions_) {
1619 if (FLAG_trace_profiler) {
1620 THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n",
1621 sample_index,
1622 frame_index,
1623 function->Name(),
1624 token_position.ToCString(),
1625 sample->At(frame_index));
1626 }
1597 function->Tick(IsExecutingFrame(sample, frame_index), 1627 function->Tick(IsExecutingFrame(sample, frame_index),
1598 sample_index, 1628 sample_index,
1599 token_position); 1629 token_position);
1600 } 1630 }
1601 function->AddProfileCode(code_index); 1631 function->AddProfileCode(code_index);
1602 current = current->GetChild(function->table_index()); 1632 current = current->GetChild(function->table_index());
1603 if (ShouldTickNode(sample, frame_index)) { 1633 if (ShouldTickNode(sample, frame_index)) {
1604 current->Tick(); 1634 current->Tick();
1605 } 1635 }
1606 current->AddCodeObjectIndex(code_index); 1636 current->AddCodeObjectIndex(code_index);
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 2131
2102 void Profile::Build(Thread* thread, 2132 void Profile::Build(Thread* thread,
2103 SampleFilter* filter, 2133 SampleFilter* filter,
2104 TagOrder tag_order, 2134 TagOrder tag_order,
2105 intptr_t extra_tags) { 2135 intptr_t extra_tags) {
2106 ProfileBuilder builder(thread, filter, tag_order, extra_tags, this); 2136 ProfileBuilder builder(thread, filter, tag_order, extra_tags, this);
2107 builder.Build(); 2137 builder.Build();
2108 } 2138 }
2109 2139
2110 2140
2141 intptr_t Profile::NumFunctions() const {
2142 return functions_->length();
2143 }
2144
2111 ProfileFunction* Profile::GetFunction(intptr_t index) { 2145 ProfileFunction* Profile::GetFunction(intptr_t index) {
2112 ASSERT(functions_ != NULL); 2146 ASSERT(functions_ != NULL);
2113 return functions_->At(index); 2147 return functions_->At(index);
2114 } 2148 }
2115 2149
2116 2150
2117 ProfileCode* Profile::GetCode(intptr_t index) { 2151 ProfileCode* Profile::GetCode(intptr_t index) {
2118 ASSERT(live_code_ != NULL); 2152 ASSERT(live_code_ != NULL);
2119 ASSERT(dead_code_ != NULL); 2153 ASSERT(dead_code_ != NULL);
2120 ASSERT(tag_code_ != NULL); 2154 ASSERT(tag_code_ != NULL);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 2251
2218 ProfileTrieNode* trie = sample->timeline_trie(); 2252 ProfileTrieNode* trie = sample->timeline_trie();
2219 ASSERT(trie->frame_id() != -1); 2253 ASSERT(trie->frame_id() != -1);
2220 event.AddPropertyF("sf", "%" Pd "-%" Pd, 2254 event.AddPropertyF("sf", "%" Pd "-%" Pd,
2221 isolate_id, trie->frame_id()); 2255 isolate_id, trie->frame_id());
2222 } 2256 }
2223 } 2257 }
2224 } 2258 }
2225 2259
2226 2260
2261 ProfileFunction* Profile::FindFunction(const Function& function) {
2262 const intptr_t index = functions_->LookupIndex(function);
2263 if (index < 0) {
2264 return NULL;
2265 }
2266 return functions_->At(index);
2267 }
2268
2269
2227 void Profile::PrintProfileJSON(JSONStream* stream) { 2270 void Profile::PrintProfileJSON(JSONStream* stream) {
2228 ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler); 2271 ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
2229 JSONObject obj(stream); 2272 JSONObject obj(stream);
2230 obj.AddProperty("type", "_CpuProfile"); 2273 obj.AddProperty("type", "_CpuProfile");
2231 PrintHeaderJSON(&obj); 2274 PrintHeaderJSON(&obj);
2232 { 2275 {
2233 JSONArray codes(&obj, "codes"); 2276 JSONArray codes(&obj, "codes");
2234 for (intptr_t i = 0; i < live_code_->length(); i++) { 2277 for (intptr_t i = 0; i < live_code_->length(); i++) {
2235 ProfileCode* code = live_code_->At(i); 2278 ProfileCode* code = live_code_->At(i);
2236 ASSERT(code != NULL); 2279 ASSERT(code != NULL);
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 // Disable thread interrupts while processing the buffer. 2590 // Disable thread interrupts while processing the buffer.
2548 DisableThreadInterruptsScope dtis(thread); 2591 DisableThreadInterruptsScope dtis(thread);
2549 2592
2550 ClearProfileVisitor clear_profile(isolate); 2593 ClearProfileVisitor clear_profile(isolate);
2551 sample_buffer->VisitSamples(&clear_profile); 2594 sample_buffer->VisitSamples(&clear_profile);
2552 } 2595 }
2553 2596
2554 #endif // !PRODUCT 2597 #endif // !PRODUCT
2555 2598
2556 } // namespace dart 2599 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698