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

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

Issue 2684763002: 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
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | no next file » | 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 22245 matching lines...) Expand 10 before | Expand all | Expand 10 after
22256 return reinterpret_cast<RawClosure*>(raw); 22256 return reinterpret_cast<RawClosure*>(raw);
22257 } 22257 }
22258 22258
22259 22259
22260 intptr_t StackTrace::Length() const { 22260 intptr_t StackTrace::Length() const {
22261 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22261 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22262 return code_array.Length(); 22262 return code_array.Length();
22263 } 22263 }
22264 22264
22265 22265
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 { 22266 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const {
22273 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22267 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22274 return reinterpret_cast<RawCode*>(code_array.At(frame_index)); 22268 return reinterpret_cast<RawCode*>(code_array.At(frame_index));
22275 } 22269 }
22276 22270
22277 22271
22278 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { 22272 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const {
22279 const Array& code_array = Array::Handle(raw_ptr()->code_array_); 22273 const Array& code_array = Array::Handle(raw_ptr()->code_array_);
22280 code_array.SetAt(frame_index, code); 22274 code_array.SetAt(frame_index, code);
22281 } 22275 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
22330 return result.raw(); 22324 return result.raw();
22331 } 22325 }
22332 22326
22333 22327
22334 const char* StackTrace::ToCString() const { 22328 const char* StackTrace::ToCString() const {
22335 intptr_t idx = 0; 22329 intptr_t idx = 0;
22336 return ToCStringInternal(&idx); 22330 return ToCStringInternal(&idx);
22337 } 22331 }
22338 22332
22339 22333
22340 static intptr_t PrintOneStackTrace(Zone* zone, 22334 static void PrintStackTraceFrame(Zone* zone,
22341 GrowableArray<char*>* frame_strings, 22335 TextBuffer* buffer,
22342 uword pc, 22336 const Function& function,
22343 const Function& function, 22337 TokenPosition token_pos,
22344 const Code& code, 22338 intptr_t frame_index) {
22345 intptr_t frame_index) {
22346 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
22347 const Script& script = Script::Handle(zone, function.script()); 22339 const Script& script = Script::Handle(zone, function.script());
22348 const String& function_name = 22340 const String& function_name =
22349 String::Handle(zone, function.QualifiedUserVisibleName()); 22341 String::Handle(zone, function.QualifiedUserVisibleName());
22350 const String& url = String::Handle( 22342 const String& url = String::Handle(
22351 zone, script.IsNull() ? String::New("Kernel") : script.url()); 22343 zone, script.IsNull() ? String::New("Kernel") : script.url());
22352 intptr_t line = -1; 22344 intptr_t line = -1;
22353 intptr_t column = -1; 22345 intptr_t column = -1;
22354 if (!script.IsNull() && token_pos.IsReal()) { 22346 if (!script.IsNull() && token_pos.IsReal()) {
22355 if (script.HasSource() || script.kind() == RawScript::kKernelTag) { 22347 if (script.HasSource() || script.kind() == RawScript::kKernelTag) {
22356 script.GetTokenLocation(token_pos, &line, &column); 22348 script.GetTokenLocation(token_pos, &line, &column);
22357 } else { 22349 } else {
22358 script.GetTokenLocation(token_pos, &line, NULL); 22350 script.GetTokenLocation(token_pos, &line, NULL);
22359 } 22351 }
22360 } 22352 }
22361 char* chars = NULL;
22362 if (column >= 0) { 22353 if (column >= 0) {
22363 chars = 22354 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index,
22364 OS::SCreate(zone, "#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index, 22355 function_name.ToCString(), url.ToCString(), line, column);
22365 function_name.ToCString(), url.ToCString(), line, column);
22366 } else if (line >= 0) { 22356 } else if (line >= 0) {
22367 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, 22357 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index,
22368 function_name.ToCString(), url.ToCString(), line); 22358 function_name.ToCString(), url.ToCString(), line);
22369 } else { 22359 } else {
22370 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s)\n", frame_index, 22360 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index,
22371 function_name.ToCString(), url.ToCString()); 22361 function_name.ToCString(), url.ToCString());
22372 } 22362 }
22373 frame_strings->Add(chars);
22374 return strlen(chars);
22375 } 22363 }
22376 22364
22377 22365
22378 const char* StackTrace::ToCStringInternal(intptr_t* frame_index, 22366 const char* StackTrace::ToCStringInternal(intptr_t* frame_index,
22379 intptr_t max_frames) const { 22367 intptr_t max_frames) const {
22380 Zone* zone = Thread::Current()->zone(); 22368 Zone* zone = Thread::Current()->zone();
22381 Function& function = Function::Handle(); 22369 Function& function = Function::Handle(zone);
22382 Code& code = Code::Handle(); 22370 Code& code = Code::Handle(zone);
22371 GrowableArray<const Function*> inlined_functions;
22372 GrowableArray<TokenPosition> inlined_token_positions;
22373 TextBuffer buffer(1024);
22374
22383 // Iterate through the stack frames and create C string description 22375 // Iterate through the stack frames and create C string description
22384 // for each frame. 22376 // for each frame.
22385 intptr_t total_len = 0;
22386 GrowableArray<char*> frame_strings;
22387 for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) { 22377 for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) {
22388 function = FunctionAtFrame(i); 22378 code = CodeAtFrame(i);
22389 if (function.IsNull()) { 22379 if (code.IsNull()) {
22390 // Check for a null function, which indicates a gap in a StackOverflow or 22380 // Check for a null function, which indicates a gap in a StackOverflow or
22391 // OutOfMemory trace. 22381 // OutOfMemory trace.
22392 if ((i < (Length() - 1)) && 22382 if ((i < (Length() - 1)) && (CodeAtFrame(i + 1) != Code::null())) {
22393 (FunctionAtFrame(i + 1) != Function::null())) { 22383 buffer.AddString("...\n...\n");
22394 const char* kTruncated = "...\n...\n";
22395 intptr_t truncated_len = strlen(kTruncated) + 1;
22396 char* chars = zone->Alloc<char>(truncated_len);
22397 OS::SNPrint(chars, truncated_len, "%s", kTruncated);
22398 frame_strings.Add(chars);
22399 total_len += truncated_len;
22400 ASSERT(PcOffsetAtFrame(i) != Smi::null()); 22384 ASSERT(PcOffsetAtFrame(i) != Smi::null());
22401 // To account for gap frames. 22385 // To account for gap frames.
22402 (*frame_index) += Smi::Value(PcOffsetAtFrame(i)); 22386 (*frame_index) += Smi::Value(PcOffsetAtFrame(i));
22403 } 22387 }
22404 } else { 22388 } else {
22405 code = CodeAtFrame(i); 22389 // Stub code is not included in the stack trace.
22406 ASSERT(function.raw() == code.function()); 22390 ASSERT(code.IsFunctionCode());
22407 uword pc = code.PayloadStart() + Smi::Value(PcOffsetAtFrame(i)); 22391
22392 intptr_t pc_offset = Smi::Value(PcOffsetAtFrame(i));
22408 if (code.is_optimized() && expand_inlined() && 22393 if (code.is_optimized() && expand_inlined() &&
22409 !FLAG_precompiled_runtime) { 22394 !FLAG_precompiled_runtime) {
22410 // Traverse inlined frames. 22395 // Convert return address to call address. Compare the profiler's
22411 for (InlinedFunctionsIterator it(code, pc); 22396 // OffsetForPC.
22412 !it.Done() && (*frame_index < max_frames); it.Advance()) { 22397 intptr_t effective_pc_offset = pc_offset - 1;
22413 function = it.function(); 22398 code.GetInlinedFunctionsAt(effective_pc_offset, &inlined_functions,
22414 if (function.is_visible() || FLAG_show_invisible_frames) { 22399 &inlined_token_positions);
22415 code = it.code(); 22400 ASSERT(inlined_functions.length() >= 1);
22416 ASSERT(function.raw() == code.function()); 22401 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
22417 uword pc = it.pc(); 22402 if (inlined_functions[j]->is_visible() ||
22418 ASSERT(pc != 0); 22403 FLAG_show_invisible_frames) {
22419 ASSERT(code.PayloadStart() <= pc); 22404 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j],
22420 ASSERT(pc < (code.PayloadStart() + code.Size())); 22405 inlined_token_positions[j], *frame_index);
22421 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function, 22406 (*frame_index)++;
22422 code, *frame_index);
22423 (*frame_index)++; // To account for inlined frames.
22424 } 22407 }
22425 } 22408 }
22426 } else { 22409 } else {
22410 function = code.function();
22427 if (function.is_visible() || FLAG_show_invisible_frames) { 22411 if (function.is_visible() || FLAG_show_invisible_frames) {
22428 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function, 22412 uword pc = code.PayloadStart() + pc_offset;
22429 code, *frame_index); 22413 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
22414 PrintStackTraceFrame(zone, &buffer, function, token_pos,
22415 *frame_index);
22430 (*frame_index)++; 22416 (*frame_index)++;
22431 } 22417 }
22432 } 22418 }
22433 } 22419 }
22434 } 22420 }
22435 22421
22436 // Now concatenate the frame descriptions into a single C string. 22422 return buffer.Steal();
22437 char* chars = zone->Alloc<char>(total_len + 1);
22438 intptr_t index = 0;
22439 for (intptr_t i = 0; i < frame_strings.length(); i++) {
22440 index += OS::SNPrint((chars + index), (total_len + 1 - index), "%s",
22441 frame_strings[i]);
22442 }
22443 chars[total_len] = '\0';
22444 return chars;
22445 } 22423 }
22446 22424
22447 22425
22448 void RegExp::set_pattern(const String& pattern) const { 22426 void RegExp::set_pattern(const String& pattern) const {
22449 StorePointer(&raw_ptr()->pattern_, pattern.raw()); 22427 StorePointer(&raw_ptr()->pattern_, pattern.raw());
22450 } 22428 }
22451 22429
22452 22430
22453 void RegExp::set_function(intptr_t cid, 22431 void RegExp::set_function(intptr_t cid,
22454 bool sticky, 22432 bool sticky,
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
22759 return UserTag::null(); 22737 return UserTag::null();
22760 } 22738 }
22761 22739
22762 22740
22763 const char* UserTag::ToCString() const { 22741 const char* UserTag::ToCString() const {
22764 const String& tag_label = String::Handle(label()); 22742 const String& tag_label = String::Handle(label());
22765 return tag_label.ToCString(); 22743 return tag_label.ToCString();
22766 } 22744 }
22767 22745
22768 } // namespace dart 22746 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698