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

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

Issue 2993253002: Make line-starts 32-bits TypedData instead of Array of smis.
Patch Set: Created 3 years, 4 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | 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 9005 matching lines...) Expand 10 before | Expand all | Expand 10 after
9016 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { 9016 RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
9017 Zone* zone = Thread::Current()->zone(); 9017 Zone* zone = Thread::Current()->zone();
9018 const GrowableObjectArray& info = 9018 const GrowableObjectArray& info =
9019 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); 9019 GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
9020 const String& source = String::Handle(zone, Source()); 9020 const String& source = String::Handle(zone, Source());
9021 const String& key = Symbols::Empty(); 9021 const String& key = Symbols::Empty();
9022 const Object& line_separator = Object::Handle(zone); 9022 const Object& line_separator = Object::Handle(zone);
9023 Smi& value = Smi::Handle(zone); 9023 Smi& value = Smi::Handle(zone);
9024 9024
9025 if (kind() == RawScript::kKernelTag) { 9025 if (kind() == RawScript::kKernelTag) {
9026 const Array& line_starts_array = Array::Handle(line_starts()); 9026 const TypedData& line_starts_data = TypedData::Handle(line_starts());
9027 if (line_starts_array.IsNull()) { 9027 if (line_starts_data.IsNull()) {
9028 // Scripts in the AOT snapshot do not have a line starts array. 9028 // Scripts in the AOT snapshot do not have a line starts array.
9029 // A well-formed line number array has a leading null. 9029 // A well-formed line number array has a leading null.
9030 info.Add(line_separator); // New line. 9030 info.Add(line_separator); // New line.
9031 return info.raw(); 9031 return info.raw();
9032 } 9032 }
9033 intptr_t line_count = line_starts_array.Length(); 9033 intptr_t line_count = line_starts_data.Length();
9034 ASSERT(line_count > 0); 9034 ASSERT(line_count > 0);
9035 const Array& debug_positions_array = Array::Handle(debug_positions()); 9035 const Array& debug_positions_array = Array::Handle(debug_positions());
9036 intptr_t token_count = debug_positions_array.Length(); 9036 intptr_t token_count = debug_positions_array.Length();
9037 int token_index = 0; 9037 int token_index = 0;
9038 9038
9039 for (int line_index = 0; line_index < line_count; ++line_index) { 9039 for (int line_index = 0; line_index < line_count; ++line_index) {
9040 value ^= line_starts_array.At(line_index); 9040 intptr_t start = line_starts_data.GetUint32(line_index << 2);
9041 intptr_t start = value.Value();
9042 // Output the rest of the tokens if we have no next line. 9041 // Output the rest of the tokens if we have no next line.
9043 intptr_t end = TokenPosition::kMaxSourcePos; 9042 intptr_t end = TokenPosition::kMaxSourcePos;
9044 if (line_index + 1 < line_count) { 9043 if (line_index + 1 < line_count) {
9045 value ^= line_starts_array.At(line_index + 1); 9044 end = line_starts_data.GetUint32((line_index + 1) << 2);
9046 end = value.Value();
9047 } 9045 }
9048 bool first = true; 9046 bool first = true;
9049 while (token_index < token_count) { 9047 while (token_index < token_count) {
9050 value ^= debug_positions_array.At(token_index); 9048 value ^= debug_positions_array.At(token_index);
9051 intptr_t debug_position = value.Value(); 9049 intptr_t debug_position = value.Value();
9052 if (debug_position >= end) break; 9050 if (debug_position >= end) break;
9053 9051
9054 if (first) { 9052 if (first) {
9055 info.Add(line_separator); // New line. 9053 info.Add(line_separator); // New line.
9056 value = Smi::New(line_index + 1); // Line number. 9054 value = Smi::New(line_index + 1); // Line number.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
9168 } 9166 }
9169 9167
9170 void Script::set_resolved_url(const String& value) const { 9168 void Script::set_resolved_url(const String& value) const {
9171 StorePointer(&raw_ptr()->resolved_url_, value.raw()); 9169 StorePointer(&raw_ptr()->resolved_url_, value.raw());
9172 } 9170 }
9173 9171
9174 void Script::set_source(const String& value) const { 9172 void Script::set_source(const String& value) const {
9175 StorePointer(&raw_ptr()->source_, value.raw()); 9173 StorePointer(&raw_ptr()->source_, value.raw());
9176 } 9174 }
9177 9175
9178 void Script::set_line_starts(const Array& value) const { 9176 void Script::set_line_starts(const TypedData& value) const {
9179 StorePointer(&raw_ptr()->line_starts_, value.raw()); 9177 StorePointer(&raw_ptr()->line_starts_, value.raw());
9180 } 9178 }
9181 9179
9182 void Script::set_debug_positions(const Array& value) const { 9180 void Script::set_debug_positions(const Array& value) const {
9183 StorePointer(&raw_ptr()->debug_positions_, value.raw()); 9181 StorePointer(&raw_ptr()->debug_positions_, value.raw());
9184 } 9182 }
9185 9183
9186 void Script::set_yield_positions(const Array& value) const { 9184 void Script::set_yield_positions(const Array& value) const {
9187 StorePointer(&raw_ptr()->yield_positions_, value.raw()); 9185 StorePointer(&raw_ptr()->yield_positions_, value.raw());
9188 } 9186 }
9189 9187
9190 RawArray* Script::yield_positions() const { 9188 RawArray* Script::yield_positions() const {
9191 #if !defined(DART_PRECOMPILED_RUNTIME) 9189 #if !defined(DART_PRECOMPILED_RUNTIME)
9192 Array& yields = Array::Handle(raw_ptr()->yield_positions_); 9190 Array& yields = Array::Handle(raw_ptr()->yield_positions_);
9193 if (yields.IsNull() && kind() == RawScript::kKernelTag) { 9191 if (yields.IsNull() && kind() == RawScript::kKernelTag) {
9194 // This is created lazily. Now we need it. 9192 // This is created lazily. Now we need it.
9195 kernel::CollectTokenPositionsFor(*this); 9193 kernel::CollectTokenPositionsFor(*this);
9196 } 9194 }
9197 #endif // !defined(DART_PRECOMPILED_RUNTIME) 9195 #endif // !defined(DART_PRECOMPILED_RUNTIME)
9198 return raw_ptr()->yield_positions_; 9196 return raw_ptr()->yield_positions_;
9199 } 9197 }
9200 9198
9201 RawArray* Script::line_starts() const { 9199 RawTypedData* Script::line_starts() const {
9202 return raw_ptr()->line_starts_; 9200 return raw_ptr()->line_starts_;
9203 } 9201 }
9204 9202
9205 RawArray* Script::debug_positions() const { 9203 RawArray* Script::debug_positions() const {
9206 #if !defined(DART_PRECOMPILED_RUNTIME) 9204 #if !defined(DART_PRECOMPILED_RUNTIME)
9207 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); 9205 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_);
9208 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { 9206 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) {
9209 // This is created lazily. Now we need it. 9207 // This is created lazily. Now we need it.
9210 kernel::CollectTokenPositionsFor(*this); 9208 kernel::CollectTokenPositionsFor(*this);
9211 } 9209 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
9256 } 9254 }
9257 9255
9258 // Specialized for AOT compilation, which does this lookup for every token 9256 // Specialized for AOT compilation, which does this lookup for every token
9259 // position that could be part of a stack trace. 9257 // position that could be part of a stack trace.
9260 intptr_t Script::GetTokenLineUsingLineStarts( 9258 intptr_t Script::GetTokenLineUsingLineStarts(
9261 TokenPosition target_token_pos) const { 9259 TokenPosition target_token_pos) const {
9262 if (target_token_pos.IsNoSource()) { 9260 if (target_token_pos.IsNoSource()) {
9263 return 0; 9261 return 0;
9264 } 9262 }
9265 Zone* zone = Thread::Current()->zone(); 9263 Zone* zone = Thread::Current()->zone();
9266 Array& line_starts_array = Array::Handle(zone, line_starts()); 9264 TypedData& line_starts_data = TypedData::Handle(zone, line_starts());
9267 Smi& token_pos = Smi::Handle(zone); 9265 if (line_starts_data.IsNull()) {
9268 if (line_starts_array.IsNull()) {
9269 ASSERT(kind() != RawScript::kKernelTag); 9266 ASSERT(kind() != RawScript::kKernelTag);
9270 GrowableObjectArray& line_starts_list = 9267 GrowableArray<intptr_t> line_starts_list(10);
9271 GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
9272 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); 9268 const TokenStream& tkns = TokenStream::Handle(zone, tokens());
9273 TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource, 9269 TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource,
9274 TokenStream::Iterator::kAllTokens); 9270 TokenStream::Iterator::kAllTokens);
9275 intptr_t cur_line = line_offset() + 1; 9271 intptr_t cur_line = line_offset() + 1;
9276 token_pos = Smi::New(0); 9272 intptr_t token_pos = 0;
9277 line_starts_list.Add(token_pos); 9273 line_starts_list.Add(token_pos);
9278 while (tkit.CurrentTokenKind() != Token::kEOS) { 9274 while (tkit.CurrentTokenKind() != Token::kEOS) {
9279 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { 9275 if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
9280 cur_line++; 9276 cur_line++;
9281 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); 9277 token_pos = tkit.CurrentPosition().value() + 1;
9282 line_starts_list.Add(token_pos); 9278 line_starts_list.Add(token_pos);
9283 } 9279 }
9284 tkit.Advance(); 9280 tkit.Advance();
9285 } 9281 }
9286 line_starts_array = Array::MakeFixedLength(line_starts_list); 9282
9287 set_line_starts(line_starts_array); 9283 intptr_t length = line_starts_list.length();
9284 line_starts_data =
9285 TypedData::New(kTypedDataUint32ArrayCid, length, Heap::kOld);
9286 for (intptr_t i = 0; i < length; ++i) {
9287 line_starts_data.SetUint32(i << 2, line_starts_list.At(i));
9288 }
9289
9290 set_line_starts(line_starts_data);
9288 } 9291 }
9289 9292
9290 ASSERT(line_starts_array.Length() > 0); 9293 ASSERT(line_starts_data.Length() > 0);
9291 intptr_t offset = target_token_pos.Pos(); 9294 intptr_t offset = target_token_pos.Pos();
9292 intptr_t min = 0; 9295 intptr_t min = 0;
9293 intptr_t max = line_starts_array.Length() - 1; 9296 intptr_t max = line_starts_data.Length() - 1;
9294 9297
9295 // Binary search to find the line containing this offset. 9298 // Binary search to find the line containing this offset.
9296 while (min < max) { 9299 while (min < max) {
9297 int midpoint = (max - min + 1) / 2 + min; 9300 int midpoint = (max - min + 1) / 2 + min;
9298 token_pos ^= line_starts_array.At(midpoint); 9301 intptr_t value = line_starts_data.GetUint32(midpoint << 2);
9299 if (token_pos.Value() > offset) { 9302 if (value > offset) {
9300 max = midpoint - 1; 9303 max = midpoint - 1;
9301 } else { 9304 } else {
9302 min = midpoint; 9305 min = midpoint;
9303 } 9306 }
9304 } 9307 }
9305 return min + 1; // Line numbers start at 1. 9308 return min + 1; // Line numbers start at 1.
9306 } 9309 }
9307 9310
9308 void Script::GetTokenLocation(TokenPosition token_pos, 9311 void Script::GetTokenLocation(TokenPosition token_pos,
9309 intptr_t* line, 9312 intptr_t* line,
9310 intptr_t* column, 9313 intptr_t* column,
9311 intptr_t* token_len) const { 9314 intptr_t* token_len) const {
9312 ASSERT(line != NULL); 9315 ASSERT(line != NULL);
9313 Zone* zone = Thread::Current()->zone(); 9316 Zone* zone = Thread::Current()->zone();
9314 9317
9315 if (kind() == RawScript::kKernelTag) { 9318 if (kind() == RawScript::kKernelTag) {
9316 const Array& line_starts_array = Array::Handle(zone, line_starts()); 9319 const TypedData& line_starts_data = TypedData::Handle(zone, line_starts());
9317 if (line_starts_array.IsNull()) { 9320 if (line_starts_data.IsNull()) {
9318 // Scripts in the AOT snapshot do not have a line starts array. 9321 // Scripts in the AOT snapshot do not have a line starts array.
9319 *line = -1; 9322 *line = -1;
9320 if (column != NULL) { 9323 if (column != NULL) {
9321 *column = -1; 9324 *column = -1;
9322 } 9325 }
9323 if (token_len != NULL) { 9326 if (token_len != NULL) {
9324 *token_len = 1; 9327 *token_len = 1;
9325 } 9328 }
9326 return; 9329 return;
9327 } 9330 }
9328 ASSERT(line_starts_array.Length() > 0); 9331 ASSERT(line_starts_data.Length() > 0);
9329 intptr_t offset = token_pos.value(); 9332 intptr_t offset = token_pos.value();
9330 intptr_t min = 0; 9333 intptr_t min = 0;
9331 intptr_t max = line_starts_array.Length() - 1; 9334 intptr_t max = line_starts_data.Length() - 1;
9332 9335
9333 // Binary search to find the line containing this offset. 9336 // Binary search to find the line containing this offset.
9334 Smi& smi = Smi::Handle(zone);
9335 while (min < max) { 9337 while (min < max) {
9336 intptr_t midpoint = (max - min + 1) / 2 + min; 9338 intptr_t midpoint = (max - min + 1) / 2 + min;
9337 9339 intptr_t value = line_starts_data.GetUint32(midpoint << 2);
9338 smi ^= line_starts_array.At(midpoint); 9340 if (value > offset) {
9339 if (smi.Value() > offset) {
9340 max = midpoint - 1; 9341 max = midpoint - 1;
9341 } else { 9342 } else {
9342 min = midpoint; 9343 min = midpoint;
9343 } 9344 }
9344 } 9345 }
9345 *line = min + 1; // Line numbers start at 1. 9346 *line = min + 1; // Line numbers start at 1.
9346 smi ^= line_starts_array.At(min); 9347 intptr_t value = line_starts_data.GetUint32(min << 2);
9347 if (column != NULL) { 9348 if (column != NULL) {
9348 *column = offset - smi.Value() + 1; 9349 *column = offset - value + 1;
9349 } 9350 }
9350 if (token_len != NULL) { 9351 if (token_len != NULL) {
9351 // We don't explicitly save this data: Load the source 9352 // We don't explicitly save this data: Load the source
9352 // and find it from there. 9353 // and find it from there.
9353 const String& source = String::Handle(zone, Source()); 9354 const String& source = String::Handle(zone, Source());
9354 *token_len = 1; 9355 *token_len = 1;
9355 if (offset < source.Length() && 9356 if (offset < source.Length() &&
9356 Scanner::IsIdentStartChar(source.CharAt(offset))) { 9357 Scanner::IsIdentStartChar(source.CharAt(offset))) {
9357 for (intptr_t i = offset + 1; 9358 for (intptr_t i = offset + 1;
9358 i < source.Length() && Scanner::IsIdentChar(source.CharAt(i)); 9359 i < source.Length() && Scanner::IsIdentChar(source.CharAt(i));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
9410 } 9411 }
9411 } 9412 }
9412 9413
9413 void Script::TokenRangeAtLine(intptr_t line_number, 9414 void Script::TokenRangeAtLine(intptr_t line_number,
9414 TokenPosition* first_token_index, 9415 TokenPosition* first_token_index,
9415 TokenPosition* last_token_index) const { 9416 TokenPosition* last_token_index) const {
9416 ASSERT(first_token_index != NULL && last_token_index != NULL); 9417 ASSERT(first_token_index != NULL && last_token_index != NULL);
9417 ASSERT(line_number > 0); 9418 ASSERT(line_number > 0);
9418 9419
9419 if (kind() == RawScript::kKernelTag) { 9420 if (kind() == RawScript::kKernelTag) {
9420 const Array& line_starts_array = Array::Handle(line_starts()); 9421 const TypedData& line_starts_data = TypedData::Handle(line_starts());
9421 if (line_starts_array.IsNull()) { 9422 if (line_starts_data.IsNull()) {
9422 // Scripts in the AOT snapshot do not have a line starts array. 9423 // Scripts in the AOT snapshot do not have a line starts array.
9423 *first_token_index = TokenPosition::kNoSource; 9424 *first_token_index = TokenPosition::kNoSource;
9424 *last_token_index = TokenPosition::kNoSource; 9425 *last_token_index = TokenPosition::kNoSource;
9425 return; 9426 return;
9426 } 9427 }
9427 ASSERT(line_starts_array.Length() >= line_number); 9428 ASSERT(line_starts_data.Length() >= line_number);
9428 Smi& value = Smi::Handle(); 9429 intptr_t value = line_starts_data.GetUint32((line_number - 1) << 2);
9429 value ^= line_starts_array.At(line_number - 1); 9430 *first_token_index = TokenPosition(value);
9430 *first_token_index = TokenPosition(value.Value()); 9431 if (line_starts_data.Length() > line_number) {
9431 if (line_starts_array.Length() > line_number) { 9432 value = line_starts_data.GetUint32(line_number << 2);
9432 value ^= line_starts_array.At(line_number); 9433 *last_token_index = TokenPosition(value - 1);
9433 *last_token_index = TokenPosition(value.Value() - 1);
9434 } else { 9434 } else {
9435 // Length of source is last possible token in this script. 9435 // Length of source is last possible token in this script.
9436 *last_token_index = TokenPosition(String::Handle(Source()).Length()); 9436 *last_token_index = TokenPosition(String::Handle(Source()).Length());
9437 } 9437 }
9438 return; 9438 return;
9439 } 9439 }
9440 9440
9441 Zone* zone = Thread::Current()->zone(); 9441 Zone* zone = Thread::Current()->zone();
9442 *first_token_index = TokenPosition::kNoSource; 9442 *first_token_index = TokenPosition::kNoSource;
9443 *last_token_index = TokenPosition::kNoSource; 9443 *last_token_index = TokenPosition::kNoSource;
(...skipping 13090 matching lines...) Expand 10 before | Expand all | Expand 10 after
22534 } 22534 }
22535 return UserTag::null(); 22535 return UserTag::null();
22536 } 22536 }
22537 22537
22538 const char* UserTag::ToCString() const { 22538 const char* UserTag::ToCString() const {
22539 const String& tag_label = String::Handle(label()); 22539 const String& tag_label = String::Handle(label());
22540 return tag_label.ToCString(); 22540 return tag_label.ToCString();
22541 } 22541 }
22542 22542
22543 } // namespace dart 22543 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698