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

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

Issue 2686813006: Reapply "Use CodeSourceMap for stack traces (still JIT only)." (Closed)
Patch Set: Created 3 years, 10 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/object.h ('k') | runtime/vm/profiler_service.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 29 matching lines...) Expand all
40 #include "vm/scopes.h" 40 #include "vm/scopes.h"
41 #include "vm/stack_frame.h" 41 #include "vm/stack_frame.h"
42 #include "vm/symbols.h" 42 #include "vm/symbols.h"
43 #include "vm/tags.h" 43 #include "vm/tags.h"
44 #include "vm/thread_registry.h" 44 #include "vm/thread_registry.h"
45 #include "vm/timeline.h" 45 #include "vm/timeline.h"
46 #include "vm/timer.h" 46 #include "vm/timer.h"
47 #include "vm/type_table.h" 47 #include "vm/type_table.h"
48 #include "vm/unicode.h" 48 #include "vm/unicode.h"
49 #include "vm/weak_code.h" 49 #include "vm/weak_code.h"
50 #include "vm/zone_text_buffer.h"
50 51
51 namespace dart { 52 namespace dart {
52 53
53 DEFINE_FLAG(int, 54 DEFINE_FLAG(int,
54 huge_method_cutoff_in_code_size, 55 huge_method_cutoff_in_code_size,
55 200000, 56 200000,
56 "Huge method cutoff in unoptimized code size (in bytes)."); 57 "Huge method cutoff in unoptimized code size (in bytes).");
57 DEFINE_FLAG( 58 DEFINE_FLAG(
58 bool, 59 bool,
59 overlap_type_arguments, 60 overlap_type_arguments,
(...skipping 14393 matching lines...) Expand 10 before | Expand all | Expand 10 after
14453 // If we are missing a stack map, this must either be unoptimized code, or 14454 // If we are missing a stack map, this must either be unoptimized code, or
14454 // the entry to an osr function. (In which case all stack slots are 14455 // the entry to an osr function. (In which case all stack slots are
14455 // considered to have tagged pointers.) 14456 // considered to have tagged pointers.)
14456 // Running with --verify-on-transition should hit this. 14457 // Running with --verify-on-transition should hit this.
14457 ASSERT(!is_optimized() || 14458 ASSERT(!is_optimized() ||
14458 (pc_offset == UncheckedEntryPoint() - PayloadStart())); 14459 (pc_offset == UncheckedEntryPoint() - PayloadStart()));
14459 return StackMap::null(); 14460 return StackMap::null();
14460 } 14461 }
14461 14462
14462 14463
14463 void Code::GetInlinedFunctionsAt( 14464 void Code::GetInlinedFunctionsAtInstruction(
14464 intptr_t pc_offset, 14465 intptr_t pc_offset,
14465 GrowableArray<const Function*>* functions, 14466 GrowableArray<const Function*>* functions,
14466 GrowableArray<TokenPosition>* token_positions) const { 14467 GrowableArray<TokenPosition>* token_positions) const {
14467 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); 14468 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14468 if (map.IsNull()) { 14469 if (map.IsNull()) {
14469 // Stub code. 14470 // Stub code.
14470 return; 14471 return;
14471 } 14472 }
14472 const Array& id_map = Array::Handle(inlined_id_to_function()); 14473 const Array& id_map = Array::Handle(inlined_id_to_function());
14473 const Function& root = Function::Handle(function()); 14474 const Function& root = Function::Handle(function());
(...skipping 7782 matching lines...) Expand 10 before | Expand all | Expand 10 after
22256 return reinterpret_cast<RawClosure*>(raw); 22257 return reinterpret_cast<RawClosure*>(raw);
22257 } 22258 }
22258 22259
22259 22260
22260 intptr_t StackTrace::Length() const { 22261 intptr_t StackTrace::Length() const {
22261 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22262 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22262 return code_array.Length(); 22263 return code_array.Length();
22263 } 22264 }
22264 22265
22265 22266
22266 RawFunction* StackTrace::FunctionAtFrame(intptr_t frame_index) const {
22267 const Code& code = Code::Handle(CodeAtFrame(frame_index));
22268 return code.IsNull() ? Function::null() : code.function();
22269 }
22270
22271
22272 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const { 22267 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const {
22273 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22268 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22274 return reinterpret_cast<RawCode*>(code_array.At(frame_index)); 22269 return reinterpret_cast<RawCode*>(code_array.At(frame_index));
22275 } 22270 }
22276 22271
22277 22272
22278 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { 22273 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const {
22279 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22274 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22280 code_array.SetAt(frame_index, code); 22275 code_array.SetAt(frame_index, code);
22281 } 22276 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
22354 return result.raw(); 22349 return result.raw();
22355 } 22350 }
22356 22351
22357 22352
22358 const char* StackTrace::ToCString() const { 22353 const char* StackTrace::ToCString() const {
22359 intptr_t idx = 0; 22354 intptr_t idx = 0;
22360 return ToCStringInternal(*this, &idx); 22355 return ToCStringInternal(*this, &idx);
22361 } 22356 }
22362 22357
22363 22358
22364 static intptr_t PrintOneStackTrace(Zone* zone, 22359 static void PrintStackTraceFrame(Zone* zone,
22365 GrowableArray<char*>* frame_strings, 22360 ZoneTextBuffer* buffer,
22366 uword pc, 22361 const Function& function,
22367 const Function& function, 22362 TokenPosition token_pos,
22368 const Code& code, 22363 intptr_t frame_index) {
22369 intptr_t frame_index) {
22370 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
22371 const Script& script = Script::Handle(zone, function.script()); 22364 const Script& script = Script::Handle(zone, function.script());
22372 const String& function_name = 22365 const String& function_name =
22373 String::Handle(zone, function.QualifiedUserVisibleName()); 22366 String::Handle(zone, function.QualifiedUserVisibleName());
22374 const String& url = String::Handle( 22367 const String& url = String::Handle(
22375 zone, script.IsNull() ? String::New("Kernel") : script.url()); 22368 zone, script.IsNull() ? String::New("Kernel") : script.url());
22376 intptr_t line = -1; 22369 intptr_t line = -1;
22377 intptr_t column = -1; 22370 intptr_t column = -1;
22378 if (!script.IsNull() && token_pos.IsReal()) { 22371 if (!script.IsNull() && token_pos.IsReal()) {
22379 if (script.HasSource() || script.kind() == RawScript::kKernelTag) { 22372 if (script.HasSource() || script.kind() == RawScript::kKernelTag) {
22380 script.GetTokenLocation(token_pos, &line, &column); 22373 script.GetTokenLocation(token_pos, &line, &column);
22381 } else { 22374 } else {
22382 script.GetTokenLocation(token_pos, &line, NULL); 22375 script.GetTokenLocation(token_pos, &line, NULL);
22383 } 22376 }
22384 } 22377 }
22385 char* chars = NULL;
22386 if (column >= 0) { 22378 if (column >= 0) {
22387 chars = 22379 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index,
22388 OS::SCreate(zone, "#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index, 22380 function_name.ToCString(), url.ToCString(), line, column);
22389 function_name.ToCString(), url.ToCString(), line, column);
22390 } else if (line >= 0) { 22381 } else if (line >= 0) {
22391 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, 22382 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index,
22392 function_name.ToCString(), url.ToCString(), line); 22383 function_name.ToCString(), url.ToCString(), line);
22393 } else { 22384 } else {
22394 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s)\n", frame_index, 22385 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index,
22395 function_name.ToCString(), url.ToCString()); 22386 function_name.ToCString(), url.ToCString());
22396 } 22387 }
22397 frame_strings->Add(chars);
22398 return strlen(chars);
22399 } 22388 }
22400 22389
22401 22390
22402 const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in, 22391 const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in,
22403 intptr_t* frame_index, 22392 intptr_t* frame_index,
22404 intptr_t max_frames) { 22393 intptr_t max_frames) {
22405 Zone* zone = Thread::Current()->zone(); 22394 Zone* zone = Thread::Current()->zone();
22395 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw());
22406 Function& function = Function::Handle(zone); 22396 Function& function = Function::Handle(zone);
22407 Code& code = Code::Handle(zone); 22397 Code& code = Code::Handle(zone);
22398 GrowableArray<const Function*> inlined_functions;
22399 GrowableArray<TokenPosition> inlined_token_positions;
22400 ZoneTextBuffer buffer(zone, 1024);
22401
22408 // Iterate through the stack frames and create C string description 22402 // Iterate through the stack frames and create C string description
22409 // for each frame. 22403 // for each frame.
22410 intptr_t total_len = 0; 22404 do {
22411 GrowableArray<char*> frame_strings;
22412 StackTrace& stack_trace = StackTrace::Handle(zone);
22413 stack_trace ^= stack_trace_in.raw();
22414 while (!stack_trace.IsNull()) {
22415 for (intptr_t i = 0; 22405 for (intptr_t i = 0;
22416 (i < stack_trace.Length()) && (*frame_index < max_frames); i++) { 22406 (i < stack_trace.Length()) && (*frame_index < max_frames); i++) {
22417 code = stack_trace.CodeAtFrame(i); 22407 code = stack_trace.CodeAtFrame(i);
22418 function = stack_trace.FunctionAtFrame(i); 22408 if (code.IsNull()) {
22419 if (code.raw() == StubCode::AsynchronousGapMarker_entry()->code()) {
22420 const char* kAsyncSuspension = "<asynchronous suspension>\n";
22421 intptr_t async_suspension_len = strlen(kAsyncSuspension) + 1;
22422 char* chars = zone->Alloc<char>(async_suspension_len);
22423 OS::SNPrint(chars, async_suspension_len, "%s", kAsyncSuspension);
22424 frame_strings.Add(chars);
22425 total_len += async_suspension_len;
22426 } else if (function.IsNull()) {
22427 // Check for a null function, which indicates a gap in a StackOverflow 22409 // Check for a null function, which indicates a gap in a StackOverflow
22428 // or OutOfMemory trace. 22410 // or OutOfMemory trace.
22429 if ((i < (stack_trace.Length() - 1)) && 22411 if ((i < (stack_trace.Length() - 1)) &&
22430 (stack_trace.FunctionAtFrame(i + 1) != Function::null())) { 22412 (stack_trace.CodeAtFrame(i + 1) != Code::null())) {
22431 const char* kTruncated = "...\n...\n"; 22413 buffer.AddString("...\n...\n");
22432 intptr_t truncated_len = strlen(kTruncated) + 1;
22433 char* chars = zone->Alloc<char>(truncated_len);
22434 OS::SNPrint(chars, truncated_len, "%s", kTruncated);
22435 frame_strings.Add(chars);
22436 total_len += truncated_len;
22437 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null()); 22414 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null());
22438 // To account for gap frames. 22415 // To account for gap frames.
22439 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i)); 22416 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i));
22440 } 22417 }
22418 } else if (code.raw() ==
22419 StubCode::AsynchronousGapMarker_entry()->code()) {
22420 buffer.AddString("<asynchronous suspension>\n");
22441 } else { 22421 } else {
22442 code = stack_trace.CodeAtFrame(i); 22422 ASSERT(code.IsFunctionCode());
22443 ASSERT(function.raw() == code.function()); 22423 intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i));
22444 uword pc =
22445 code.PayloadStart() + Smi::Value(stack_trace.PcOffsetAtFrame(i));
22446 if (code.is_optimized() && stack_trace.expand_inlined() && 22424 if (code.is_optimized() && stack_trace.expand_inlined() &&
22447 !FLAG_precompiled_runtime) { 22425 !FLAG_precompiled_runtime) {
22448 // Traverse inlined frames. 22426 code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions,
22449 for (InlinedFunctionsIterator it(code, pc); 22427 &inlined_token_positions);
22450 !it.Done() && (*frame_index < max_frames); it.Advance()) { 22428 ASSERT(inlined_functions.length() >= 1);
22451 function = it.function(); 22429 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
22452 if (function.is_visible() || FLAG_show_invisible_frames) { 22430 if (inlined_functions[j]->is_visible() ||
22453 code = it.code(); 22431 FLAG_show_invisible_frames) {
22454 ASSERT(function.raw() == code.function()); 22432 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j],
22455 uword pc = it.pc(); 22433 inlined_token_positions[j], *frame_index);
22456 ASSERT(pc != 0); 22434 (*frame_index)++;
22457 ASSERT(code.PayloadStart() <= pc);
22458 ASSERT(pc < (code.PayloadStart() + code.Size()));
22459 total_len += PrintOneStackTrace(zone, &frame_strings, pc,
22460 function, code, *frame_index);
22461 (*frame_index)++; // To account for inlined frames.
22462 } 22435 }
22463 } 22436 }
22464 } else { 22437 } else {
22438 function = code.function();
22465 if (function.is_visible() || FLAG_show_invisible_frames) { 22439 if (function.is_visible() || FLAG_show_invisible_frames) {
22466 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function, 22440 uword pc = code.PayloadStart() + pc_offset;
22467 code, *frame_index); 22441 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
22442 PrintStackTraceFrame(zone, &buffer, function, token_pos,
22443 *frame_index);
22468 (*frame_index)++; 22444 (*frame_index)++;
22469 } 22445 }
22470 } 22446 }
22471 } 22447 }
22472 } 22448 }
22473 // Follow the link. 22449 // Follow the link.
22474 stack_trace ^= stack_trace.async_link(); 22450 stack_trace ^= stack_trace.async_link();
22475 } 22451 } while (!stack_trace.IsNull());
22476 22452
22477 // Now concatenate the frame descriptions into a single C string. 22453 return buffer.buffer();
22478 char* chars = zone->Alloc<char>(total_len + 1);
22479 intptr_t index = 0;
22480 for (intptr_t i = 0; i < frame_strings.length(); i++) {
22481 index += OS::SNPrint((chars + index), (total_len + 1 - index), "%s",
22482 frame_strings[i]);
22483 }
22484 chars[total_len] = '\0';
22485 return chars;
22486 } 22454 }
22487 22455
22488 22456
22489 void RegExp::set_pattern(const String& pattern) const { 22457 void RegExp::set_pattern(const String& pattern) const {
22490 StorePointer(&raw_ptr()->pattern_, pattern.raw()); 22458 StorePointer(&raw_ptr()->pattern_, pattern.raw());
22491 } 22459 }
22492 22460
22493 22461
22494 void RegExp::set_function(intptr_t cid, 22462 void RegExp::set_function(intptr_t cid,
22495 bool sticky, 22463 bool sticky,
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
22800 return UserTag::null(); 22768 return UserTag::null();
22801 } 22769 }
22802 22770
22803 22771
22804 const char* UserTag::ToCString() const { 22772 const char* UserTag::ToCString() const {
22805 const String& tag_label = String::Handle(label()); 22773 const String& tag_label = String::Handle(label());
22806 return tag_label.ToCString(); 22774 return tag_label.ToCString();
22807 } 22775 }
22808 22776
22809 } // namespace dart 22777 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698