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:
parent
69b96e608a
commit
899bef8226
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user