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

Side by Side Diff: src/objects.cc

Issue 1986173002: Refactor script position calculation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove Script.line_ends Created 4 years, 7 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 12360 matching lines...) Expand 10 before | Expand all | Expand 10 after
12371 Handle<FixedArray> array = String::CalculateLineEnds(src, true); 12371 Handle<FixedArray> array = String::CalculateLineEnds(src, true);
12372 12372
12373 if (*array != isolate->heap()->empty_fixed_array()) { 12373 if (*array != isolate->heap()->empty_fixed_array()) {
12374 array->set_map(isolate->heap()->fixed_cow_array_map()); 12374 array->set_map(isolate->heap()->fixed_cow_array_map());
12375 } 12375 }
12376 12376
12377 script->set_line_ends(*array); 12377 script->set_line_ends(*array);
12378 DCHECK(script->line_ends()->IsFixedArray()); 12378 DCHECK(script->line_ends()->IsFixedArray());
12379 } 12379 }
12380 12380
12381 bool Script::GetPositionInfo(Handle<Script> script, int position,
12382 PositionInfo* info, bool with_offset) {
12383 InitLineEnds(script);
Yang 2016/05/18 13:23:09 You can avoid this wrapper if you do something lik
jgruber1 2016/05/19 08:05:24 I used the wrapper in order to keep Script::GetLin
jgruber1 2016/05/19 08:56:01 Done, removed the static wrapper.
12384 return script->GetPositionInfo(position, info, with_offset);
12385 }
12386
12387 #define SMI_VALUE(x) (Smi::cast(x)->value())
12388 bool Script::GetPositionInfo(int position, PositionInfo* info,
12389 bool with_offset) {
12390 DisallowHeapAllocation no_allocation;
12391
12392 DCHECK(line_ends()->IsFixedArray());
12393 FixedArray* ends = FixedArray::cast(line_ends());
12394
12395 const int ends_len = ends->length();
12396 if (ends_len == 0) return false;
12397
12398 // Return early on invalid positions. Negative positions behave as if 0 was
12399 // passed, and positions beyond the end of the script return as failure.
12400 if (position < 0) {
12401 position = 0;
12402 } else if (position > SMI_VALUE(ends->get(ends_len - 1))) {
12403 return false;
12404 }
12405
12406 // Determine line number by doing a binary search on the line ends array.
12407 if (SMI_VALUE(ends->get(0)) >= position) {
12408 info->line = 0;
12409 info->line_start = 0;
12410 info->column = position;
12411 } else {
12412 int left = 0;
12413 int right = ends_len - 1;
12414
12415 while (right > 0) {
12416 const int mid = (left + right) / 2;
12417 if (right < left) {
Yang 2016/05/18 13:23:09 Let's just DCHECK_GE(right, left);
jgruber1 2016/05/19 08:05:24 Done (DCHECK_LT(left, right)).
12418 UNREACHABLE();
12419 } else if (position > SMI_VALUE(ends->get(mid))) {
12420 left = mid + 1;
12421 } else if (position <= SMI_VALUE(ends->get(mid - 1))) {
12422 right = mid - 1;
12423 } else {
12424 info->line = mid;
12425 break;
12426 }
12427 }
12428 DCHECK(SMI_VALUE(ends->get(info->line)) >= position &&
12429 SMI_VALUE(ends->get(info->line - 1)) < position);
12430 info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1;
12431 info->column = position - info->line_start;
12432 }
12433
12434 // Line end is position of the linebreak character.
12435 info->line_end = SMI_VALUE(ends->get(info->line));
12436 if (info->line_end > 0) {
12437 DCHECK(source()->IsString());
12438 Handle<String> src(String::cast(source()));
12439 if (src->Get(info->line_end - 1) == '\r') {
12440 info->line_end--;
12441 }
12442 }
12443
12444 // Add offsets if requested.
12445 if (with_offset) {
12446 if (info->line == 0) {
12447 info->column += column_offset();
12448 }
12449 info->line += line_offset();
12450 }
12451
12452 return true;
12453 }
12454 #undef SMI_VALUE
12381 12455
12382 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { 12456 int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
12383 int line_number = GetLineNumber(script, code_pos); 12457 PositionInfo info;
12384 if (line_number == -1) return -1; 12458 if (!GetPositionInfo(script, code_pos, &info, true)) {
12459 return -1;
12460 }
12385 12461
12386 DisallowHeapAllocation no_allocation; 12462 return info.column;
12387 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); 12463 }
12388 line_number = line_number - script->line_offset(); 12464
12389 if (line_number == 0) return code_pos + script->column_offset(); 12465 int Script::GetLineNumberWithArray(int code_pos) {
12390 int prev_line_end_pos = 12466 PositionInfo info;
12391 Smi::cast(line_ends_array->get(line_number - 1))->value(); 12467 if (!GetPositionInfo(code_pos, &info, true)) {
12392 return code_pos - (prev_line_end_pos + 1); 12468 return -1;
12469 }
12470
12471 return info.line;
12393 } 12472 }
12394 12473
12395 12474
12396 int Script::GetLineNumberWithArray(int code_pos) {
12397 DisallowHeapAllocation no_allocation;
12398 DCHECK(line_ends()->IsFixedArray());
12399 FixedArray* line_ends_array = FixedArray::cast(line_ends());
12400 int line_ends_len = line_ends_array->length();
12401 if (line_ends_len == 0) return -1;
12402
12403 if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
12404 return line_offset();
12405 }
12406
12407 int left = 0;
12408 int right = line_ends_len;
12409 while (int half = (right - left) / 2) {
12410 if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
12411 right -= half;
12412 } else {
12413 left += half;
12414 }
12415 }
12416 return right + line_offset();
12417 }
12418
12419
12420 int Script::GetLineNumber(Handle<Script> script, int code_pos) { 12475 int Script::GetLineNumber(Handle<Script> script, int code_pos) {
12421 InitLineEnds(script); 12476 InitLineEnds(script);
12422 return script->GetLineNumberWithArray(code_pos); 12477 return script->GetLineNumberWithArray(code_pos);
12423 } 12478 }
12424 12479
12425 12480
12426 int Script::GetLineNumber(int code_pos) { 12481 int Script::GetLineNumber(int code_pos) {
12427 DisallowHeapAllocation no_allocation; 12482 DisallowHeapAllocation no_allocation;
12428 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos); 12483 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos);
12429 12484
(...skipping 5951 matching lines...) Expand 10 before | Expand all | Expand 10 after
18381 if (cell->value() != *new_value) { 18436 if (cell->value() != *new_value) {
18382 cell->set_value(*new_value); 18437 cell->set_value(*new_value);
18383 Isolate* isolate = cell->GetIsolate(); 18438 Isolate* isolate = cell->GetIsolate();
18384 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18439 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18385 isolate, DependentCode::kPropertyCellChangedGroup); 18440 isolate, DependentCode::kPropertyCellChangedGroup);
18386 } 18441 }
18387 } 18442 }
18388 18443
18389 } // namespace internal 18444 } // namespace internal
18390 } // namespace v8 18445 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698