Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index b28e24f98366a43da798f1aa26a00356152f1a80..43c8b2e581afd4a37c8409892a4db0b2c3870ca9 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -15373,7 +15373,7 @@ const char* Stacktrace::ToCStringInternal(intptr_t* frame_index) const { |
| for (intptr_t i = 0; i < Length(); i++) { |
| function = FunctionAtFrame(i); |
| if (function.IsNull()) { |
| - // Check if null function object indicates a stack trace overflow. |
| + // Check for null function object, which indicates a stack trace overflow. |
|
siva
2013/10/31 17:13:26
A null function object doesn't necessarily mean a
rmacnak
2013/11/07 21:31:12
Reverted.
|
| if ((i < (Length() - 1)) && |
| (FunctionAtFrame(i + 1) != Function::null())) { |
| const char* kTruncated = "...\n...\n"; |
| @@ -15421,6 +15421,124 @@ const char* Stacktrace::ToCStringInternal(intptr_t* frame_index) const { |
| return chars; |
| } |
| +intptr_t Stacktrace::VisibleLength() const { |
| + // Isolate* isolate = Isolate::Current(); |
| + Function& function = Function::Handle(); |
| + Code& code = Code::Handle(); |
| + intptr_t frame_count = 0; |
| + for (intptr_t i = 0; i < Length(); i++) { |
| + function = FunctionAtFrame(i); |
| + if (function.IsNull()) { |
| + // Check for null function object, which indicates a stack trace overflow. |
| + if ((i < (Length() - 1)) && |
| + (FunctionAtFrame(i + 1) != Function::null())) { |
| + // How to inform API users? |
|
rmacnak
2013/10/30 16:52:45
frame_count++ if we indicate the gap. See comment
siva
2013/10/31 17:13:26
Since you are handing out actual frames maybe the
rmacnak
2013/11/07 21:31:12
The truncation for StackOverflow happens before th
|
| + } |
| + } else if (function.is_visible() || FLAG_verbose_stacktrace) { |
|
siva
2013/10/31 17:13:26
We probably don't want the verbose_stacktrace flag
rmacnak
2013/11/07 21:31:12
Removed.
|
| + 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(); it.Advance()) { |
| + function = it.function(); |
| + 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())); |
| + frame_count++; |
| + } |
| + } else { |
| + frame_count++; |
| + } |
| + } |
| + } |
| + return frame_count; |
| +} |
| + |
| +bool Stacktrace::VisibleFrameInfoAt(intptr_t frame_index, |
| + String* function_name, |
| + String* script_url, |
| + intptr_t* line_number, |
| + intptr_t* col_num) const { |
| + ASSERT(function_name); |
| + ASSERT(script_url); |
| + ASSERT(line_number); |
| + ASSERT(col_num); |
| + |
| + if (frame_index < 0) { |
| + return false; |
| + } |
| + |
| + Isolate* isolate = Isolate::Current(); |
| + Function& function = Function::Handle(); |
| + Code& code = Code::Handle(); |
| + intptr_t frame_count = 0; |
| + for (intptr_t i = 0; i < Length(); i++) { |
| + function = FunctionAtFrame(i); |
| + if (function.IsNull()) { |
| + // Check for null function object, which indicates a stack trace overflow. |
| + if ((i < (Length() - 1)) && |
| + (FunctionAtFrame(i + 1) != Function::null())) { |
| + // How to inform API users? |
|
rmacnak
2013/10/30 16:52:45
Function named '...' at -1, -1?
siva
2013/10/31 17:13:26
Ditto comment as above, the API implementation sho
|
| + } |
| + } else if (function.is_visible() || FLAG_verbose_stacktrace) { |
| + 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(); it.Advance()) { |
| + function = it.function(); |
| + 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())); |
| + |
| + if (frame_count == frame_index) { |
| + *function_name = function.QualifiedUserVisibleName(); |
|
rmacnak
2013/10/30 16:52:45
Might allocate.
|
| + const Script& script = Script::Handle(isolate, function.script()); |
| + *script_url = script.url(); |
| + const intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
| + if (token_pos >= 0) { |
| + if (script.HasSource()) { |
| + script.GetTokenLocation(token_pos, line_number, col_num); |
| + } else { |
| + script.GetTokenLocation(token_pos, line_number, NULL); |
| + *col_num = -1; |
| + } |
| + } |
| + return true; |
| + } |
| + frame_count++; |
| + } |
| + } else { |
| + if (frame_count == frame_index) { |
| + *function_name = function.QualifiedUserVisibleName(); |
|
rmacnak
2013/10/30 16:52:45
Might allocate.
|
| + const Script& script = Script::Handle(isolate, function.script()); |
| + *script_url = script.url(); |
| + const intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
| + if (token_pos >= 0) { |
| + if (script.HasSource()) { |
| + script.GetTokenLocation(token_pos, line_number, col_num); |
| + } else { |
| + script.GetTokenLocation(token_pos, line_number, NULL); |
| + *col_num = -1; |
| + } |
| + } |
| + return true; |
| + } |
| + frame_count++; |
| + } |
| + } |
| + } |
| + return false; |
| +} |
| + |
| void JSRegExp::set_pattern(const String& pattern) const { |
| StorePointer(&raw_ptr()->pattern_, pattern.raw()); |