Chromium Code Reviews| Index: src/handles.cc |
| diff --git a/src/handles.cc b/src/handles.cc |
| index 1364951b714ceb2c87731312f77ff1427ad98f5f..63c2af27cd139f148e16befe860943d098ec3a3c 100644 |
| --- a/src/handles.cc |
| +++ b/src/handles.cc |
| @@ -37,6 +37,7 @@ |
| #include "global-handles.h" |
| #include "natives.h" |
| #include "runtime.h" |
| +#include "string-search.h" |
| #include "stub-cache.h" |
| namespace v8 { |
| @@ -508,43 +509,53 @@ void InitScriptLineEnds(Handle<Script> script) { |
| } |
| -Handle<FixedArray> CalculateLineEnds(Handle<String> src, |
| - bool with_imaginary_last_new_line) { |
| - const int src_len = src->length(); |
| - Handle<String> new_line = Factory::NewStringFromAscii(CStrVector("\n")); |
| +template <typename SourceChar> |
| +static void CalculateLineEnds(List<int>* line_ends, |
| + Vector<const SourceChar> src, |
| + bool with_last_line) { |
| + const int src_len = src.length(); |
| + StringSearch<char, SourceChar> search(CStrVector("\n")); |
| - // Pass 1: Identify line count. |
| - int line_count = 0; |
| + // Find and record line ends. |
| int position = 0; |
| while (position != -1 && position < src_len) { |
| - position = Runtime::StringMatch(src, new_line, position); |
| + position = search.Search(src, position); |
| if (position != -1) { |
| + line_ends->Add(position); |
| position++; |
| - } |
| - if (position != -1) { |
| - line_count++; |
| - } else if (with_imaginary_last_new_line) { |
| + } else if (with_last_line) { |
| // Even if the last line misses a line end, it is counted. |
| - line_count++; |
| + line_ends->Add(src_len); |
| + return; |
| } |
| } |
| +} |
| - // Pass 2: Fill in line ends positions |
| - Handle<FixedArray> array = Factory::NewFixedArray(line_count); |
| - int array_index = 0; |
| - position = 0; |
| - while (position != -1 && position < src_len) { |
| - position = Runtime::StringMatch(src, new_line, position); |
| - if (position != -1) { |
| - array->set(array_index++, Smi::FromInt(position++)); |
| - } else if (with_imaginary_last_new_line) { |
| - // If the script does not end with a line ending add the final end |
| - // position as just past the last line ending. |
| - array->set(array_index++, Smi::FromInt(src_len)); |
| + |
| +Handle<FixedArray> CalculateLineEnds(Handle<String> src, |
| + bool with_last_line) { |
| + if (!src->IsFlat()) FlattenString(src); |
|
Vyacheslav Egorov (Chromium)
2010/11/18 10:36:08
src = FlattenGetString(src)?
this will allow to r
Lasse Reichstein
2010/11/18 10:40:55
Done.
|
| + // Rough estimate of line count based on a roughly estimated average |
| + // length of (unpacked) code. |
| + int line_count_estimate = src->length() >> 4; |
| + List<int> line_ends(line_count_estimate); |
| + { |
| + AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| + // Extract flattened substring of cons string before determining asciiness. |
| + String* seq_src = *src; |
| + if (seq_src->IsConsString()) seq_src = ConsString::cast(seq_src)->first(); |
| + // Dispatch on type of strings. |
| + if (seq_src->IsAsciiRepresentation()) { |
| + CalculateLineEnds(&line_ends, seq_src->ToAsciiVector(), with_last_line); |
| + } else { |
| + CalculateLineEnds(&line_ends, seq_src->ToUC16Vector(), with_last_line); |
| } |
| } |
| - ASSERT(array_index == line_count); |
| - |
| + int line_count = line_ends.length(); |
| + Handle<FixedArray> array = Factory::NewFixedArray(line_count); |
| + for (int i = 0; i < line_count; i++) { |
| + array->set(i, Smi::FromInt(line_ends[i])); |
| + } |
| return array; |
| } |
| @@ -556,11 +567,11 @@ int GetScriptLineNumber(Handle<Script> script, int code_pos) { |
| FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); |
| const int line_ends_len = line_ends_array->length(); |
| - if (!line_ends_len) |
| - return -1; |
| + if (!line_ends_len) return -1; |
| - if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) |
| + if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) { |
| return script->line_offset()->value(); |
| + } |
| int left = 0; |
| int right = line_ends_len; |