Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 62b9d21d152631168232a70ef5d7ca7a35fc15e1..8ac0bc693e32e78e5fd4bac8d2b3958d2db0da0b 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -9077,6 +9077,54 @@ void Script::SetLocationOffset(intptr_t line_offset, |
| } |
| +// Specialized for AOT compilation, which does this lookup for every token |
| +// position that could be part of a stack trace. |
| +intptr_t Script::GetTokenLineUsingLineStarts(TokenPosition token_pos) const { |
| + Zone* zone = Thread::Current()->zone(); |
| + Array& line_starts_array = Array::Handle(zone, line_starts()); |
| + if (line_starts_array.IsNull()) { |
| + ASSERT(kind() != RawScript::kKernelTag); |
| + GrowableObjectArray& line_starts_list = |
| + GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| + const TokenStream& tkns = TokenStream::Handle(zone, tokens()); |
| + TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource, |
| + TokenStream::Iterator::kAllTokens); |
| + intptr_t cur_line = line_offset() + 1; |
| + Smi& token_pos = Smi::Handle(zone); |
|
siva
2017/02/11 03:19:00
this smi could be hoisted above and shared with th
rmacnak
2017/02/13 18:25:34
Done.
|
| + token_pos = Smi::New(0); |
| + line_starts_list.Add(token_pos); |
| + while (tkit.CurrentTokenKind() != Token::kEOS) { |
| + if (tkit.CurrentTokenKind() == Token::kNEWLINE) { |
| + cur_line++; |
| + token_pos = Smi::New(tkit.CurrentPosition().value() + 1); |
| + line_starts_list.Add(token_pos); |
| + } |
| + tkit.Advance(); |
| + } |
| + line_starts_array = Array::MakeArray(line_starts_list); |
| + set_line_starts(line_starts_array); |
| + } |
| + |
| + ASSERT(line_starts_array.Length() > 0); |
| + intptr_t offset = token_pos.value(); |
| + intptr_t min = 0; |
| + intptr_t max = line_starts_array.Length() - 1; |
| + |
| + // Binary search to find the line containing this offset. |
| + Smi& smi = Smi::Handle(zone); |
| + while (min < max) { |
| + int midpoint = (max - min + 1) / 2 + min; |
| + smi ^= line_starts_array.At(midpoint); |
| + if (smi.Value() > offset) { |
| + max = midpoint - 1; |
| + } else { |
| + min = midpoint; |
| + } |
| + } |
| + return min + 1; |
|
siva
2017/02/11 03:19:00
The + 1 here is because line numbers start from 1
rmacnak
2017/02/13 18:25:34
Yes, added comment.
|
| +} |
| + |
| + |
| void Script::GetTokenLocation(TokenPosition token_pos, |
| intptr_t* line, |
| intptr_t* column, |
| @@ -9085,7 +9133,7 @@ void Script::GetTokenLocation(TokenPosition token_pos, |
| Zone* zone = Thread::Current()->zone(); |
| if (kind() == RawScript::kKernelTag) { |
| - const Array& line_starts_array = Array::Handle(line_starts()); |
| + const Array& line_starts_array = Array::Handle(zone, line_starts()); |
| if (line_starts_array.IsNull()) { |
| // Scripts in the AOT snapshot do not have a line starts array. |
| *line = -1; |
| @@ -9099,13 +9147,13 @@ void Script::GetTokenLocation(TokenPosition token_pos, |
| } |
| ASSERT(line_starts_array.Length() > 0); |
| intptr_t offset = token_pos.value(); |
| - int min = 0; |
| - int max = line_starts_array.Length() - 1; |
| + intptr_t min = 0; |
| + intptr_t max = line_starts_array.Length() - 1; |
| // Binary search to find the line containing this offset. |
| - Smi& smi = Smi::Handle(); |
| + Smi& smi = Smi::Handle(zone); |
| while (min < max) { |
| - int midpoint = (max - min + 1) / 2 + min; |
| + intptr_t midpoint = (max - min + 1) / 2 + min; |
| smi ^= line_starts_array.At(midpoint); |
| if (smi.Value() > offset) { |
| @@ -14088,21 +14136,13 @@ intptr_t Code::GetPrologueOffset() const { |
| RawArray* Code::inlined_id_to_function() const { |
| -#if defined(DART_PRECOMPILED_RUNTIME) |
| - return Array::null(); |
| -#else |
| return raw_ptr()->inlined_id_to_function_; |
| -#endif |
| } |
| void Code::set_inlined_id_to_function(const Array& value) const { |
| -#if defined(DART_PRECOMPILED_RUNTIME) |
| - UNREACHABLE(); |
| -#else |
| ASSERT(value.IsOld()); |
| StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); |
| -#endif |
| } |
| @@ -14467,8 +14507,8 @@ void Code::GetInlinedFunctionsAtInstruction( |
| GrowableArray<TokenPosition>* token_positions) const { |
| const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
| if (map.IsNull()) { |
| - // Stub code. |
| - return; |
| + ASSERT(!IsFunctionCode()); |
| + return; // VM stub or allocation stub. |
| } |
| const Array& id_map = Array::Handle(inlined_id_to_function()); |
| const Function& root = Function::Handle(function()); |
| @@ -22368,11 +22408,15 @@ static void PrintStackTraceFrame(Zone* zone, |
| zone, script.IsNull() ? String::New("Kernel") : script.url()); |
| intptr_t line = -1; |
| intptr_t column = -1; |
| - if (!script.IsNull() && token_pos.IsReal()) { |
| - if (script.HasSource() || script.kind() == RawScript::kKernelTag) { |
| - script.GetTokenLocation(token_pos, &line, &column); |
| - } else { |
| - script.GetTokenLocation(token_pos, &line, NULL); |
| + if (FLAG_precompiled_mode) { |
| + line = token_pos.value(); |
| + } else { |
| + if (!script.IsNull() && token_pos.IsReal()) { |
| + if (script.HasSource() || script.kind() == RawScript::kKernelTag) { |
| + script.GetTokenLocation(token_pos, &line, &column); |
| + } else { |
| + script.GetTokenLocation(token_pos, &line, NULL); |
| + } |
| } |
| } |
| if (column >= 0) { |
| @@ -22421,8 +22465,7 @@ const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in, |
| } else { |
| ASSERT(code.IsFunctionCode()); |
| intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); |
| - if (code.is_optimized() && stack_trace.expand_inlined() && |
| - !FLAG_precompiled_mode) { |
| + if (code.is_optimized() && stack_trace.expand_inlined()) { |
| code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, |
| &inlined_token_positions); |
| ASSERT(inlined_functions.length() >= 1); |