Use binary search in GetScriptLineNumber.
authormikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Feb 2010 12:08:10 +0000 (12:08 +0000)
committermikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Feb 2010 12:08:10 +0000 (12:08 +0000)
Patch by Ilya Tikhonovsky <loislo@chromium.org>
Original issue http://codereview.chromium.org/593108

TBR=sgjesse@chromium.org

Review URL: http://codereview.chromium.org/608012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3870 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/handles.cc
test/cctest/test-compiler.cc

index 936177d..2186c51 100644 (file)
@@ -483,25 +483,25 @@ void InitScriptLineEnds(Handle<Script> script) {
 int GetScriptLineNumber(Handle<Script> script, int code_pos) {
   InitScriptLineEnds(script);
   AssertNoAllocation no_allocation;
-  FixedArray* line_ends_array =
-      FixedArray::cast(script->line_ends());
+  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
   const int line_ends_len = line_ends_array->length();
 
-  int line = -1;
-  if (line_ends_len > 0 &&
-      code_pos <= (Smi::cast(line_ends_array->get(0)))->value()) {
-    line = 0;
-  } else {
-    for (int i = 1; i < line_ends_len; ++i) {
-      if ((Smi::cast(line_ends_array->get(i - 1)))->value() < code_pos &&
-          code_pos <= (Smi::cast(line_ends_array->get(i)))->value()) {
-        line = i;
-        break;
-      }
+  if (!line_ends_len)
+    return -1;
+
+  if ((Smi::cast(line_ends_array->get(0)))->value() > code_pos)
+    return script->line_offset()->value();
+
+  int left = 0;
+  int right = line_ends_len;
+  while (int half = (right - left) / 2) {
+    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
+      right -= half;
+    } else {
+      left += half;
     }
   }
-
-  return line != -1 ? line + script->line_offset()->value() : line;
+  return right + script->line_offset()->value();
 }
 
 
index 05c29d7..da675d7 100644 (file)
@@ -317,3 +317,27 @@ TEST(Regression236) {
   CHECK_EQ(-1, GetScriptLineNumber(script, 100));
   CHECK_EQ(-1, GetScriptLineNumber(script, -1));
 }
+
+
+TEST(GetScriptLineNumber) {
+  LocalContext env;
+  v8::HandleScope scope;
+  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+  const char function_f[] = "function f() {}";
+  const int max_rows = 1000;
+  const int buffer_size = max_rows + sizeof(function_f);
+  ScopedVector<char> buffer(buffer_size);
+  memset(buffer.start(), '\n', buffer_size - 1);
+  buffer[buffer_size - 1] = '\0';
+
+  for (int i = 0; i < max_rows; ++i) {
+    if (i > 0)
+      buffer[i - 1] = '\n';
+    memcpy(&buffer[i], function_f, sizeof(function_f) - 1);
+    v8::Handle<v8::String> script_body = v8::String::New(buffer.start());
+    v8::Script::Compile(script_body, &origin)->Run();
+    v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+        env->Global()->Get(v8::String::New("f")));
+    CHECK_EQ(i, f->GetScriptLineNumber());
+  }
+}