OLD | NEW |
---|---|
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 9059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9070 | 9070 |
9071 void Script::SetLocationOffset(intptr_t line_offset, | 9071 void Script::SetLocationOffset(intptr_t line_offset, |
9072 intptr_t col_offset) const { | 9072 intptr_t col_offset) const { |
9073 ASSERT(line_offset >= 0); | 9073 ASSERT(line_offset >= 0); |
9074 ASSERT(col_offset >= 0); | 9074 ASSERT(col_offset >= 0); |
9075 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); | 9075 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); |
9076 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); | 9076 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); |
9077 } | 9077 } |
9078 | 9078 |
9079 | 9079 |
9080 // Specialized for AOT compilation, which does this lookup for every token | |
9081 // position that could be part of a stack trace. | |
9082 intptr_t Script::GetTokenLineUsingLineStarts(TokenPosition token_pos) const { | |
9083 Zone* zone = Thread::Current()->zone(); | |
9084 Array& line_starts_array = Array::Handle(zone, line_starts()); | |
9085 if (line_starts_array.IsNull()) { | |
9086 ASSERT(kind() != RawScript::kKernelTag); | |
9087 GrowableObjectArray& line_starts_list = | |
9088 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
9089 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); | |
9090 TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource, | |
9091 TokenStream::Iterator::kAllTokens); | |
9092 intptr_t cur_line = line_offset() + 1; | |
9093 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.
| |
9094 token_pos = Smi::New(0); | |
9095 line_starts_list.Add(token_pos); | |
9096 while (tkit.CurrentTokenKind() != Token::kEOS) { | |
9097 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { | |
9098 cur_line++; | |
9099 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); | |
9100 line_starts_list.Add(token_pos); | |
9101 } | |
9102 tkit.Advance(); | |
9103 } | |
9104 line_starts_array = Array::MakeArray(line_starts_list); | |
9105 set_line_starts(line_starts_array); | |
9106 } | |
9107 | |
9108 ASSERT(line_starts_array.Length() > 0); | |
9109 intptr_t offset = token_pos.value(); | |
9110 intptr_t min = 0; | |
9111 intptr_t max = line_starts_array.Length() - 1; | |
9112 | |
9113 // Binary search to find the line containing this offset. | |
9114 Smi& smi = Smi::Handle(zone); | |
9115 while (min < max) { | |
9116 int midpoint = (max - min + 1) / 2 + min; | |
9117 smi ^= line_starts_array.At(midpoint); | |
9118 if (smi.Value() > offset) { | |
9119 max = midpoint - 1; | |
9120 } else { | |
9121 min = midpoint; | |
9122 } | |
9123 } | |
9124 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.
| |
9125 } | |
9126 | |
9127 | |
9080 void Script::GetTokenLocation(TokenPosition token_pos, | 9128 void Script::GetTokenLocation(TokenPosition token_pos, |
9081 intptr_t* line, | 9129 intptr_t* line, |
9082 intptr_t* column, | 9130 intptr_t* column, |
9083 intptr_t* token_len) const { | 9131 intptr_t* token_len) const { |
9084 ASSERT(line != NULL); | 9132 ASSERT(line != NULL); |
9085 Zone* zone = Thread::Current()->zone(); | 9133 Zone* zone = Thread::Current()->zone(); |
9086 | 9134 |
9087 if (kind() == RawScript::kKernelTag) { | 9135 if (kind() == RawScript::kKernelTag) { |
9088 const Array& line_starts_array = Array::Handle(line_starts()); | 9136 const Array& line_starts_array = Array::Handle(zone, line_starts()); |
9089 if (line_starts_array.IsNull()) { | 9137 if (line_starts_array.IsNull()) { |
9090 // Scripts in the AOT snapshot do not have a line starts array. | 9138 // Scripts in the AOT snapshot do not have a line starts array. |
9091 *line = -1; | 9139 *line = -1; |
9092 if (column != NULL) { | 9140 if (column != NULL) { |
9093 *column = -1; | 9141 *column = -1; |
9094 } | 9142 } |
9095 if (token_len != NULL) { | 9143 if (token_len != NULL) { |
9096 *token_len = 1; | 9144 *token_len = 1; |
9097 } | 9145 } |
9098 return; | 9146 return; |
9099 } | 9147 } |
9100 ASSERT(line_starts_array.Length() > 0); | 9148 ASSERT(line_starts_array.Length() > 0); |
9101 intptr_t offset = token_pos.value(); | 9149 intptr_t offset = token_pos.value(); |
9102 int min = 0; | 9150 intptr_t min = 0; |
9103 int max = line_starts_array.Length() - 1; | 9151 intptr_t max = line_starts_array.Length() - 1; |
9104 | 9152 |
9105 // Binary search to find the line containing this offset. | 9153 // Binary search to find the line containing this offset. |
9106 Smi& smi = Smi::Handle(); | 9154 Smi& smi = Smi::Handle(zone); |
9107 while (min < max) { | 9155 while (min < max) { |
9108 int midpoint = (max - min + 1) / 2 + min; | 9156 intptr_t midpoint = (max - min + 1) / 2 + min; |
9109 | 9157 |
9110 smi ^= line_starts_array.At(midpoint); | 9158 smi ^= line_starts_array.At(midpoint); |
9111 if (smi.Value() > offset) { | 9159 if (smi.Value() > offset) { |
9112 max = midpoint - 1; | 9160 max = midpoint - 1; |
9113 } else { | 9161 } else { |
9114 min = midpoint; | 9162 min = midpoint; |
9115 } | 9163 } |
9116 } | 9164 } |
9117 *line = min + 1; | 9165 *line = min + 1; |
9118 smi ^= line_starts_array.At(min); | 9166 smi ^= line_starts_array.At(min); |
(...skipping 4962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14081 // |return_address_metadata_|. | 14129 // |return_address_metadata_|. |
14082 if (object.IsNull() || !object.IsSmi()) { | 14130 if (object.IsNull() || !object.IsSmi()) { |
14083 return -1; | 14131 return -1; |
14084 } | 14132 } |
14085 return Smi::Cast(object).Value(); | 14133 return Smi::Cast(object).Value(); |
14086 #endif | 14134 #endif |
14087 } | 14135 } |
14088 | 14136 |
14089 | 14137 |
14090 RawArray* Code::inlined_id_to_function() const { | 14138 RawArray* Code::inlined_id_to_function() const { |
14091 #if defined(DART_PRECOMPILED_RUNTIME) | |
14092 return Array::null(); | |
14093 #else | |
14094 return raw_ptr()->inlined_id_to_function_; | 14139 return raw_ptr()->inlined_id_to_function_; |
14095 #endif | |
14096 } | 14140 } |
14097 | 14141 |
14098 | 14142 |
14099 void Code::set_inlined_id_to_function(const Array& value) const { | 14143 void Code::set_inlined_id_to_function(const Array& value) const { |
14100 #if defined(DART_PRECOMPILED_RUNTIME) | |
14101 UNREACHABLE(); | |
14102 #else | |
14103 ASSERT(value.IsOld()); | 14144 ASSERT(value.IsOld()); |
14104 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); | 14145 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); |
14105 #endif | |
14106 } | 14146 } |
14107 | 14147 |
14108 | 14148 |
14109 RawCode* Code::New(intptr_t pointer_offsets_length) { | 14149 RawCode* Code::New(intptr_t pointer_offsets_length) { |
14110 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { | 14150 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { |
14111 // This should be caught before we reach here. | 14151 // This should be caught before we reach here. |
14112 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", | 14152 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", |
14113 pointer_offsets_length); | 14153 pointer_offsets_length); |
14114 } | 14154 } |
14115 ASSERT(Object::code_class() != Class::null()); | 14155 ASSERT(Object::code_class() != Class::null()); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14460 return StackMap::null(); | 14500 return StackMap::null(); |
14461 } | 14501 } |
14462 | 14502 |
14463 | 14503 |
14464 void Code::GetInlinedFunctionsAtInstruction( | 14504 void Code::GetInlinedFunctionsAtInstruction( |
14465 intptr_t pc_offset, | 14505 intptr_t pc_offset, |
14466 GrowableArray<const Function*>* functions, | 14506 GrowableArray<const Function*>* functions, |
14467 GrowableArray<TokenPosition>* token_positions) const { | 14507 GrowableArray<TokenPosition>* token_positions) const { |
14468 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 14508 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
14469 if (map.IsNull()) { | 14509 if (map.IsNull()) { |
14470 // Stub code. | 14510 ASSERT(!IsFunctionCode()); |
14471 return; | 14511 return; // VM stub or allocation stub. |
14472 } | 14512 } |
14473 const Array& id_map = Array::Handle(inlined_id_to_function()); | 14513 const Array& id_map = Array::Handle(inlined_id_to_function()); |
14474 const Function& root = Function::Handle(function()); | 14514 const Function& root = Function::Handle(function()); |
14475 CodeSourceMapReader reader(map, id_map, root); | 14515 CodeSourceMapReader reader(map, id_map, root); |
14476 reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); | 14516 reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); |
14477 } | 14517 } |
14478 | 14518 |
14479 | 14519 |
14480 #ifndef PRODUCT | 14520 #ifndef PRODUCT |
14481 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { | 14521 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { |
(...skipping 7879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
22361 const Function& function, | 22401 const Function& function, |
22362 TokenPosition token_pos, | 22402 TokenPosition token_pos, |
22363 intptr_t frame_index) { | 22403 intptr_t frame_index) { |
22364 const Script& script = Script::Handle(zone, function.script()); | 22404 const Script& script = Script::Handle(zone, function.script()); |
22365 const String& function_name = | 22405 const String& function_name = |
22366 String::Handle(zone, function.QualifiedUserVisibleName()); | 22406 String::Handle(zone, function.QualifiedUserVisibleName()); |
22367 const String& url = String::Handle( | 22407 const String& url = String::Handle( |
22368 zone, script.IsNull() ? String::New("Kernel") : script.url()); | 22408 zone, script.IsNull() ? String::New("Kernel") : script.url()); |
22369 intptr_t line = -1; | 22409 intptr_t line = -1; |
22370 intptr_t column = -1; | 22410 intptr_t column = -1; |
22371 if (!script.IsNull() && token_pos.IsReal()) { | 22411 if (FLAG_precompiled_mode) { |
22372 if (script.HasSource() || script.kind() == RawScript::kKernelTag) { | 22412 line = token_pos.value(); |
22373 script.GetTokenLocation(token_pos, &line, &column); | 22413 } else { |
22374 } else { | 22414 if (!script.IsNull() && token_pos.IsReal()) { |
22375 script.GetTokenLocation(token_pos, &line, NULL); | 22415 if (script.HasSource() || script.kind() == RawScript::kKernelTag) { |
22416 script.GetTokenLocation(token_pos, &line, &column); | |
22417 } else { | |
22418 script.GetTokenLocation(token_pos, &line, NULL); | |
22419 } | |
22376 } | 22420 } |
22377 } | 22421 } |
22378 if (column >= 0) { | 22422 if (column >= 0) { |
22379 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index, | 22423 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index, |
22380 function_name.ToCString(), url.ToCString(), line, column); | 22424 function_name.ToCString(), url.ToCString(), line, column); |
22381 } else if (line >= 0) { | 22425 } else if (line >= 0) { |
22382 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, | 22426 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, |
22383 function_name.ToCString(), url.ToCString(), line); | 22427 function_name.ToCString(), url.ToCString(), line); |
22384 } else { | 22428 } else { |
22385 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, | 22429 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, |
(...skipping 28 matching lines...) Expand all Loading... | |
22414 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null()); | 22458 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null()); |
22415 // To account for gap frames. | 22459 // To account for gap frames. |
22416 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i)); | 22460 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i)); |
22417 } | 22461 } |
22418 } else if (code.raw() == | 22462 } else if (code.raw() == |
22419 StubCode::AsynchronousGapMarker_entry()->code()) { | 22463 StubCode::AsynchronousGapMarker_entry()->code()) { |
22420 buffer.AddString("<asynchronous suspension>\n"); | 22464 buffer.AddString("<asynchronous suspension>\n"); |
22421 } else { | 22465 } else { |
22422 ASSERT(code.IsFunctionCode()); | 22466 ASSERT(code.IsFunctionCode()); |
22423 intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); | 22467 intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); |
22424 if (code.is_optimized() && stack_trace.expand_inlined() && | 22468 if (code.is_optimized() && stack_trace.expand_inlined()) { |
22425 !FLAG_precompiled_mode) { | |
22426 code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, | 22469 code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, |
22427 &inlined_token_positions); | 22470 &inlined_token_positions); |
22428 ASSERT(inlined_functions.length() >= 1); | 22471 ASSERT(inlined_functions.length() >= 1); |
22429 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { | 22472 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { |
22430 if (inlined_functions[j]->is_visible() || | 22473 if (inlined_functions[j]->is_visible() || |
22431 FLAG_show_invisible_frames) { | 22474 FLAG_show_invisible_frames) { |
22432 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j], | 22475 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j], |
22433 inlined_token_positions[j], *frame_index); | 22476 inlined_token_positions[j], *frame_index); |
22434 (*frame_index)++; | 22477 (*frame_index)++; |
22435 } | 22478 } |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
22768 return UserTag::null(); | 22811 return UserTag::null(); |
22769 } | 22812 } |
22770 | 22813 |
22771 | 22814 |
22772 const char* UserTag::ToCString() const { | 22815 const char* UserTag::ToCString() const { |
22773 const String& tag_label = String::Handle(label()); | 22816 const String& tag_label = String::Handle(label()); |
22774 return tag_label.ToCString(); | 22817 return tag_label.ToCString(); |
22775 } | 22818 } |
22776 | 22819 |
22777 } // namespace dart | 22820 } // namespace dart |
OLD | NEW |