Add test to expose bug 528
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 27 Nov 2009 07:57:45 +0000 (07:57 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 27 Nov 2009 07:57:45 +0000 (07:57 +0000)
BUG=http://code.google.com/p/v8/issues/detail?id=528
TEST=cctest/test-api/Bug528
Review URL: http://codereview.chromium.org/443021

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

src/objects-debug.cc
test/cctest/test-api.cc

index 5f4792f..8413124 100644 (file)
@@ -1136,6 +1136,22 @@ void Script::ScriptPrint() {
   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 fixed array: ");
+  line_ends_fixed_array()->ShortPrint();
+  PrintF("\n - line ends js array: ");
+  line_ends_js_array()->ShortPrint();
+  PrintF("\n - eval from function: ");
+  eval_from_function()->ShortPrint();
+  PrintF("\n - eval from instructions offset: ");
+  eval_from_instructions_offset()->ShortPrint();
   PrintF("\n");
 }
 
index 3baf0cb..35c8f7b 100644 (file)
@@ -8495,3 +8495,107 @@ THREADED_TEST(SpaghettiStackReThrow) {
   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::Object> obj = v8::Object::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());
+
+  // Compilation cache size is different for Android.
+#if defined(ANDROID)
+  CHECK_EQ(1, gc_count);
+#else
+  CHECK_EQ(5, gc_count);
+#endif
+
+  // 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());
+
+  // Compilation cache size is different for Android.
+#if defined(ANDROID)
+  CHECK_EQ(1, gc_count);
+#else
+  CHECK_EQ(2, gc_count);
+#endif
+
+  // 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());
+
+  // Compilation cache size is different for Android.
+#if defined(ANDROID)
+  CHECK_EQ(2, gc_count);
+#else
+  CHECK_EQ(5, gc_count);
+#endif
+}