Use binary search in GetScriptLineNumber.

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
This commit is contained in:
mikhail.naganov@gmail.com 2010-02-16 12:08:10 +00:00
parent 69b96e608a
commit 899bef8226
2 changed files with 39 additions and 15 deletions

View 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();
}

View 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());
}
}