Merge revisions r3372 - r3374 to trunk
This is on order to try out the changes related to http://crbug.com/23058 on trunk before merging them to the beta branch.
Review URL: http://codereview.chromium.org/449010
git-svn-id: http://v8.googlecode.com/svn/trunk@3376 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/include/v8.h b/include/v8.h
index 78b4613..dddc492 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -598,7 +598,7 @@
* with the debugger as this data object is only available through the
* debugger API.
*/
- void SetData(Handle<Value> data);
+ void SetData(Handle<String> data);
};
@@ -2634,7 +2634,7 @@
* with the debugger to provide additional information on the context through
* the debugger API.
*/
- void SetData(Handle<Value> data);
+ void SetData(Handle<String> data);
Local<Value> GetData();
/**
diff --git a/src/accessors.cc b/src/accessors.cc
index 734c364..09a3886 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -315,14 +315,11 @@
HandleScope scope;
Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
InitScriptLineEnds(script);
- if (script->line_ends_js_array()->IsUndefined()) {
- Handle<FixedArray> line_ends_fixed_array(
- FixedArray::cast(script->line_ends_fixed_array()));
- Handle<FixedArray> copy = Factory::CopyFixedArray(line_ends_fixed_array);
- Handle<JSArray> js_array = Factory::NewJSArrayWithElements(copy);
- script->set_line_ends_js_array(*js_array);
- }
- return script->line_ends_js_array();
+ ASSERT(script->line_ends()->IsFixedArray());
+ Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
+ Handle<FixedArray> copy = Factory::CopyFixedArray(line_ends);
+ Handle<JSArray> js_array = Factory::NewJSArrayWithElements(copy);
+ return *js_array;
}
diff --git a/src/api.cc b/src/api.cc
index 220788b..3a2f8ab 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -451,7 +451,7 @@
}
-void Context::SetData(v8::Handle<Value> data) {
+void Context::SetData(v8::Handle<String> data) {
if (IsDeadCheck("v8::Context::SetData()")) return;
ENTER_V8;
{
@@ -1175,7 +1175,7 @@
}
-void Script::SetData(v8::Handle<Value> data) {
+void Script::SetData(v8::Handle<String> data) {
ON_BAILOUT("v8::Script::SetData()", return);
LOG_API("Script::SetData");
{
diff --git a/src/factory.cc b/src/factory.cc
index 3d9cd7a..c63e005 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -188,8 +188,7 @@
script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
script->set_compilation_type(Smi::FromInt(Script::COMPILATION_TYPE_HOST));
script->set_wrapper(*wrapper);
- script->set_line_ends_fixed_array(Heap::undefined_value());
- script->set_line_ends_js_array(Heap::undefined_value());
+ script->set_line_ends(Heap::undefined_value());
script->set_eval_from_function(Heap::undefined_value());
script->set_eval_from_instructions_offset(Smi::FromInt(0));
diff --git a/src/handles.cc b/src/handles.cc
index b42ad24..53fa01b 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -429,12 +429,12 @@
// Init line_ends array with code positions of line ends inside script
// source.
void InitScriptLineEnds(Handle<Script> script) {
- if (!script->line_ends_fixed_array()->IsUndefined()) return;
+ if (!script->line_ends()->IsUndefined()) return;
if (!script->source()->IsString()) {
ASSERT(script->source()->IsUndefined());
- script->set_line_ends_fixed_array(*(Factory::NewFixedArray(0)));
- ASSERT(script->line_ends_fixed_array()->IsFixedArray());
+ script->set_line_ends(*(Factory::NewFixedArray(0)));
+ ASSERT(script->line_ends()->IsFixedArray());
return;
}
@@ -467,8 +467,8 @@
}
ASSERT(array_index == line_count);
- script->set_line_ends_fixed_array(*array);
- ASSERT(script->line_ends_fixed_array()->IsFixedArray());
+ script->set_line_ends(*array);
+ ASSERT(script->line_ends()->IsFixedArray());
}
@@ -477,7 +477,7 @@
InitScriptLineEnds(script);
AssertNoAllocation no_allocation;
FixedArray* line_ends_array =
- FixedArray::cast(script->line_ends_fixed_array());
+ FixedArray::cast(script->line_ends());
const int line_ends_len = line_ends_array->length();
int line = -1;
diff --git a/src/messages.js b/src/messages.js
index 2720792..b0004b1 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -238,14 +238,15 @@
Script.prototype.lineFromPosition = function(position) {
var lower = 0;
var upper = this.lineCount() - 1;
+ var line_ends = this.line_ends;
// We'll never find invalid positions so bail right away.
- if (position > this.line_ends[upper]) {
+ if (position > line_ends[upper]) {
return -1;
}
// This means we don't have to safe-guard indexing line_ends[i - 1].
- if (position <= this.line_ends[0]) {
+ if (position <= line_ends[0]) {
return 0;
}
@@ -253,9 +254,9 @@
while (upper >= 1) {
var i = (lower + upper) >> 1;
- if (position > this.line_ends[i]) {
+ if (position > line_ends[i]) {
lower = i + 1;
- } else if (position <= this.line_ends[i - 1]) {
+ } else if (position <= line_ends[i - 1]) {
upper = i - 1;
} else {
return i;
@@ -278,8 +279,9 @@
if (line == -1) return null;
// Determine start, end and column.
- var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
- var end = this.line_ends[line];
+ var line_ends = this.line_ends;
+ var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+ var end = line_ends[line];
if (end > 0 && StringCharAt.call(this.source, end - 1) == '\r') end--;
var column = position - start;
@@ -368,8 +370,9 @@
return null;
}
- var from_position = from_line == 0 ? 0 : this.line_ends[from_line - 1] + 1;
- var to_position = to_line == 0 ? 0 : this.line_ends[to_line - 1] + 1;
+ var line_ends = this.line_ends;
+ var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
+ var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
// Return a source slice with line numbers re-adjusted to the resource.
return new SourceSlice(this, from_line + this.line_offset, to_line + this.line_offset,
@@ -391,8 +394,9 @@
}
// Return the source line.
- var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
- var end = this.line_ends[line];
+ var line_ends = this.line_ends;
+ var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+ var end = line_ends[line];
return StringSubstring.call(this.source, start, end);
}
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 19c945d..52c1613 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1140,8 +1140,7 @@
VerifyPointer(data());
VerifyPointer(wrapper());
type()->SmiVerify();
- VerifyPointer(line_ends_fixed_array());
- VerifyPointer(line_ends_js_array());
+ VerifyPointer(line_ends());
VerifyPointer(id());
}
@@ -1160,6 +1159,20 @@
type()->ShortPrint();
PrintF("\n - id: ");
id()->ShortPrint();
+ PrintF("\n - data: ");
+ data()->ShortPrint();
+ PrintF("\n - context data: ");
+ context_data()->ShortPrint();
+ PrintF("\n - wrapper: ");
+ wrapper()->ShortPrint();
+ PrintF("\n - compilation type: ");
+ compilation_type()->ShortPrint();
+ PrintF("\n - line ends: ");
+ line_ends()->ShortPrint();
+ PrintF("\n - eval from function: ");
+ eval_from_function()->ShortPrint();
+ PrintF("\n - eval from instructions offset: ");
+ eval_from_instructions_offset()->ShortPrint();
PrintF("\n");
}
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 7a6444d..069a675 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2441,8 +2441,7 @@
ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
ACCESSORS(Script, type, Smi, kTypeOffset)
ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
-ACCESSORS(Script, line_ends_fixed_array, Object, kLineEndsFixedArrayOffset)
-ACCESSORS(Script, line_ends_js_array, Object, kLineEndsJSArrayOffset)
+ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
ACCESSORS(Script, eval_from_instructions_offset, Smi,
kEvalFrominstructionsOffsetOffset)
diff --git a/src/objects.h b/src/objects.h
index d22e723..3d928cd 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3182,10 +3182,7 @@
DECL_ACCESSORS(compilation_type, Smi)
// [line_ends]: FixedArray of line ends positions.
- DECL_ACCESSORS(line_ends_fixed_array, Object)
-
- // [line_ends]: JSArray of line ends positions.
- DECL_ACCESSORS(line_ends_js_array, Object)
+ DECL_ACCESSORS(line_ends, Object)
// [eval_from_function]: for eval scripts the funcion from which eval was
// called.
@@ -3215,16 +3212,8 @@
static const int kWrapperOffset = kContextOffset + kPointerSize;
static const int kTypeOffset = kWrapperOffset + kPointerSize;
static const int kCompilationTypeOffset = kTypeOffset + kPointerSize;
- // We have the line ends array both in FixedArray form and in JSArray form.
- // The FixedArray form is useful when we don't have a context and so can't
- // create a JSArray. The JSArray form is useful when we want to see the
- // array from JS code (e.g. debug-delay.js) which cannot handle unboxed
- // FixedArray objects.
- static const int kLineEndsFixedArrayOffset =
- kCompilationTypeOffset + kPointerSize;
- static const int kLineEndsJSArrayOffset =
- kLineEndsFixedArrayOffset + kPointerSize;
- static const int kIdOffset = kLineEndsJSArrayOffset + kPointerSize;
+ static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize;
+ static const int kIdOffset = kLineEndsOffset + kPointerSize;
static const int kEvalFromFunctionOffset = kIdOffset + kPointerSize;
static const int kEvalFrominstructionsOffsetOffset =
kEvalFromFunctionOffset + kPointerSize;
diff --git a/src/version.cc b/src/version.cc
index f9dc9b7..7db59c8 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 2
#define MINOR_VERSION 0
#define BUILD_NUMBER 2
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 6791685..675ce56 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -8409,3 +8409,89 @@
v8::String::Utf8Value value(try_catch.Exception());
CHECK_EQ(0, strcmp(*value, "Hey!"));
}
+
+
+static int GetGlobalObjectsCount() {
+ int count = 0;
+ v8::internal::HeapIterator it;
+ while (it.has_next()) {
+ v8::internal::HeapObject* object = it.next();
+ if (object->IsJSGlobalObject()) {
+ count++;
+ }
+ }
+#ifdef DEBUG
+ if (count > 0) v8::internal::Heap::TracePathToGlobal();
+#endif
+ return count;
+}
+
+
+TEST(Bug528) {
+ v8::V8::Initialize();
+
+ v8::HandleScope scope;
+ v8::Persistent<Context> context;
+ int gc_count;
+
+ // Context-dependent context data creates reference from the compilation
+ // cache to the global object.
+ context = Context::New();
+ {
+ v8::HandleScope scope;
+
+ context->Enter();
+ Local<v8::String> obj = v8::String::New("");
+ context->SetData(obj);
+ CompileRun("1");
+ context->Exit();
+ }
+ context.Dispose();
+ for (gc_count = 1; gc_count < 10; gc_count++) {
+ v8::internal::Heap::CollectAllGarbage(false);
+ if (GetGlobalObjectsCount() == 0) break;
+ }
+ CHECK_EQ(0, GetGlobalObjectsCount());
+ CHECK_EQ(2, gc_count);
+
+ // Eval in a function creates reference from the compilation cache to the
+ // global object.
+ context = Context::New();
+ {
+ v8::HandleScope scope;
+
+ context->Enter();
+ CompileRun("function f(){eval('1')}; f()");
+ context->Exit();
+ }
+ context.Dispose();
+ for (gc_count = 1; gc_count < 10; gc_count++) {
+ v8::internal::Heap::CollectAllGarbage(false);
+ if (GetGlobalObjectsCount() == 0) break;
+ }
+ CHECK_EQ(0, GetGlobalObjectsCount());
+ CHECK_EQ(2, gc_count);
+
+ // Looking up the line number for an exception creates reference from the
+ // compilation cache to the global object.
+ context = Context::New();
+ {
+ v8::HandleScope scope;
+
+ context->Enter();
+ v8::TryCatch try_catch;
+ CompileRun("function f(){throw 1;}; f()");
+ CHECK(try_catch.HasCaught());
+ v8::Handle<v8::Message> message = try_catch.Message();
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(1, message->GetLineNumber());
+ context->Exit();
+ }
+ context.Dispose();
+ for (gc_count = 1; gc_count < 10; gc_count++) {
+ v8::internal::Heap::CollectAllGarbage(false);
+ if (GetGlobalObjectsCount() == 0) break;
+ }
+ CHECK_EQ(0, GetGlobalObjectsCount());
+ CHECK_EQ(2, gc_count);
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d938174..5b72193 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -5016,7 +5016,7 @@
v8::ScriptOrigin origin2 = v8::ScriptOrigin(v8::String::New("new name"));
v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2);
script2->Run();
- script2->SetData(data_obj);
+ script2->SetData(data_obj->ToString());
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
f->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
@@ -5069,8 +5069,8 @@
CHECK(context_2->GetData()->IsUndefined());
// Set and check different data values.
- v8::Handle<v8::Value> data_1 = v8::Number::New(1);
- v8::Handle<v8::Value> data_2 = v8::String::New("2");
+ v8::Handle<v8::String> data_1 = v8::String::New("1");
+ v8::Handle<v8::String> data_2 = v8::String::New("2");
context_1->SetData(data_1);
context_2->SetData(data_2);
CHECK(context_1->GetData()->StrictEquals(data_1));
@@ -5233,7 +5233,7 @@
CHECK(context_1->GetData()->IsUndefined());
// Set and check a data value.
- v8::Handle<v8::Value> data_1 = v8::Number::New(1);
+ v8::Handle<v8::String> data_1 = v8::String::New("1");
context_1->SetData(data_1);
CHECK(context_1->GetData()->StrictEquals(data_1));