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

Unified Diff: runtime/vm/object.cc

Issue 1582683003: Fall back to inlining intervals to generate stack traces in --noopt. Inlined frames will lack line … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/tests/vm/vm.status ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8e3284f3020ddb2e84329e0df43cb0984cd0afb6..4e43f454e5909bb42d6549ae3fcdca8cd5852050 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -21600,6 +21600,23 @@ static intptr_t PrintOneStacktrace(Zone* zone,
}
+static intptr_t PrintOneStacktraceNoCode(Zone* zone,
+ GrowableArray<char*>* frame_strings,
+ const Function& function,
+ intptr_t frame_index) {
+ const Script& script = Script::Handle(zone, function.script());
+ const String& function_name =
+ String::Handle(zone, function.QualifiedUserVisibleName());
+ const String& url = String::Handle(zone, script.url());
+ char* chars = NULL;
+ chars = OS::SCreate(zone,
+ "#%-6" Pd " %s (%s)\n",
+ frame_index, function_name.ToCString(), url.ToCString());
+ frame_strings->Add(chars);
+ return strlen(chars);
+}
+
+
const char* Stacktrace::ToCStringInternal(intptr_t* frame_index,
intptr_t max_frames) const {
Zone* zone = Thread::Current()->zone();
@@ -21612,7 +21629,8 @@ const char* Stacktrace::ToCStringInternal(intptr_t* frame_index,
for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) {
function = FunctionAtFrame(i);
if (function.IsNull()) {
- // Check if null function object indicates a stack trace overflow.
+ // Check if null function object indicates a gap in a StackOverflow or
+ // OutOfMemory trace.
if ((i < (Length() - 1)) &&
(FunctionAtFrame(i + 1) != Function::null())) {
const char* kTruncated = "...\n...\n";
@@ -21622,31 +21640,55 @@ const char* Stacktrace::ToCStringInternal(intptr_t* frame_index,
frame_strings.Add(chars);
total_len += truncated_len;
}
- } else if (function.is_visible() || FLAG_show_invisible_frames) {
+ } else {
code = CodeAtFrame(i);
ASSERT(function.raw() == code.function());
uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
if (code.is_optimized() && expand_inlined()) {
// Traverse inlined frames.
- for (InlinedFunctionsIterator it(code, pc);
- !it.Done() && (*frame_index < max_frames); it.Advance()) {
- function = it.function();
- if (function.is_visible() || FLAG_show_invisible_frames) {
- code = it.code();
- ASSERT(function.raw() == code.function());
- uword pc = it.pc();
- ASSERT(pc != 0);
- ASSERT(code.EntryPoint() <= pc);
- ASSERT(pc < (code.EntryPoint() + code.Size()));
- total_len += PrintOneStacktrace(
- zone, &frame_strings, pc, function, code, *frame_index);
- (*frame_index)++; // To account for inlined frames.
+ if (Compiler::allow_recompilation()) {
+ for (InlinedFunctionsIterator it(code, pc);
+ !it.Done() && (*frame_index < max_frames); it.Advance()) {
+ function = it.function();
+ if (function.is_visible() || FLAG_show_invisible_frames) {
+ code = it.code();
+ ASSERT(function.raw() == code.function());
+ uword pc = it.pc();
+ ASSERT(pc != 0);
+ ASSERT(code.EntryPoint() <= pc);
+ ASSERT(pc < (code.EntryPoint() + code.Size()));
+ total_len += PrintOneStacktrace(
+ zone, &frame_strings, pc, function, code, *frame_index);
+ (*frame_index)++; // To account for inlined frames.
+ }
+ }
+ } else {
+ // Precompilation: we don't have deopt info, so we don't know the
+ // source position of inlined functions, but we can still name them.
+ intptr_t offset = Smi::Value(PcOffsetAtFrame(i));
+ // The PC of frames below the top frame is a call's return address,
+ // which can belong to a different inlining interval than the call.
+ intptr_t effective_offset = offset - 1;
+ GrowableArray<Function*> inlined_functions;
+ code.GetInlinedFunctionsAt(effective_offset, &inlined_functions);
+ ASSERT(inlined_functions.length() >= 1); // At least the inliner.
+ for (intptr_t j = 0; j < inlined_functions.length(); j++) {
+ Function* inlined_function = inlined_functions[j];
+ ASSERT(inlined_function != NULL);
+ ASSERT(!inlined_function->IsNull());
+ if (inlined_function->is_visible() || FLAG_show_invisible_frames) {
+ total_len += PrintOneStacktraceNoCode(
+ zone, &frame_strings, *inlined_function, *frame_index);
+ (*frame_index)++;
+ }
}
}
} else {
- total_len += PrintOneStacktrace(
- zone, &frame_strings, pc, function, code, *frame_index);
- (*frame_index)++;
+ if (function.is_visible() || FLAG_show_invisible_frames) {
+ total_len += PrintOneStacktrace(
+ zone, &frame_strings, pc, function, code, *frame_index);
+ (*frame_index)++;
+ }
}
}
}
« no previous file with comments | « runtime/tests/vm/vm.status ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698