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

Unified Diff: src/handles.cc

Issue 5121007: Make count-line-ends use StringSearch and only iterate over the source once. (Closed)
Patch Set: Address review comment. Created 10 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/handles.cc
diff --git a/src/handles.cc b/src/handles.cc
index 1364951b714ceb2c87731312f77ff1427ad98f5f..3dfb886e99085e8fdf762880e22c61f4f78b24af 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,50 @@ 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) {
+ src = FlattenGetString(src);
+ // 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.
+ // Dispatch on type of strings.
+ if (src->IsAsciiRepresentation()) {
+ CalculateLineEnds(&line_ends, src->ToAsciiVector(), with_last_line);
+ } else {
+ CalculateLineEnds(&line_ends, 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 +564,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;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698