Version 2.5.1
Fixed bug causing spurious out of memory exceptions (issue http://crbug.com/54580).
Fixed compilation error on Solaris platform (issue 901).
Fixed error in strtod (string to floating point number conversion) due to glibc's use of 80-bit floats in the FPU on 32-bit linux.
Adjusted randomized allocations of executable memory to have 64k granularity (issue http://crbug.com/56036).
Supported profiling using kernel perf_events on linux. Added ll_prof script to tools and --ll-prof flag to V8.
git-svn-id: http://v8.googlecode.com/svn/trunk@5675 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index eec024f..126ac21 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -177,13 +177,11 @@
int request = 24;
CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request)));
CHECK(Smi::FromInt(42)->IsSmi());
- CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure());
- CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested());
+ CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure());
CHECK_EQ(NEW_SPACE,
- Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space());
+ Failure::RetryAfterGC(NEW_SPACE)->allocation_space());
CHECK_EQ(OLD_POINTER_SPACE,
- Failure::RetryAfterGC(request,
- OLD_POINTER_SPACE)->allocation_space());
+ Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space());
CHECK(Failure::Exception()->IsFailure());
CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi());
CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi());
@@ -195,8 +193,7 @@
v8::HandleScope sc;
// Check GC.
- int free_bytes = Heap::MaxObjectSizeInPagedSpace();
- CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+ Heap::CollectGarbage(NEW_SPACE);
Handle<String> name = Factory::LookupAsciiSymbol("theFunction");
Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot");
@@ -221,7 +218,7 @@
CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
}
- CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+ Heap::CollectGarbage(NEW_SPACE);
// Function should be alive.
CHECK(Top::context()->global()->HasLocalProperty(*name));
@@ -239,7 +236,7 @@
}
// After gc, it should survive.
- CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+ Heap::CollectGarbage(NEW_SPACE);
CHECK(Top::context()->global()->HasLocalProperty(*obj_name));
CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject());
@@ -301,7 +298,7 @@
}
// after gc, it should survive
- CHECK(Heap::CollectGarbage(0, NEW_SPACE));
+ Heap::CollectGarbage(NEW_SPACE);
CHECK((*h1)->IsString());
CHECK((*h2)->IsHeapNumber());
@@ -382,8 +379,8 @@
h2 = GlobalHandles::Create(*u);
}
- CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
- CHECK(Heap::CollectGarbage(0, NEW_SPACE));
+ Heap::CollectGarbage(OLD_POINTER_SPACE);
+ Heap::CollectGarbage(NEW_SPACE);
// Make sure the object is promoted.
GlobalHandles::MakeWeak(h2.location(),
@@ -392,7 +389,7 @@
CHECK(!GlobalHandles::IsNearDeath(h1.location()));
CHECK(!GlobalHandles::IsNearDeath(h2.location()));
- CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+ Heap::CollectGarbage(OLD_POINTER_SPACE);
CHECK((*h1)->IsString());
@@ -426,7 +423,7 @@
CHECK(!WeakPointerCleared);
// Mark-compact treats weak reference properly.
- CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+ Heap::CollectGarbage(OLD_POINTER_SPACE);
CHECK(WeakPointerCleared);
}
@@ -814,8 +811,7 @@
TEST(LargeObjectSpaceContains) {
InitializeVM();
- int free_bytes = Heap::MaxObjectSizeInPagedSpace();
- CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+ Heap::CollectGarbage(NEW_SPACE);
Address current_top = Heap::new_space()->top();
Page* page = Page::FromAddress(current_top);
@@ -958,6 +954,7 @@
CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize)));
}
+
TEST(TestCodeFlushing) {
i::FLAG_allow_natives_syntax = true;
// If we do not flush code this test is invalid.
@@ -1001,3 +998,91 @@
CHECK(function->shared()->is_compiled());
CHECK(function->is_compiled());
}
+
+
+// Count the number of global contexts in the weak list of global contexts.
+static int CountGlobalContexts() {
+ int count = 0;
+ Object* object = Heap::global_contexts_list();
+ while (!object->IsUndefined()) {
+ count++;
+ object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
+ }
+ return count;
+}
+
+
+TEST(TestInternalWeakLists) {
+ static const int kNumTestContexts = 10;
+
+ v8::HandleScope scope;
+ v8::Persistent<v8::Context> ctx[kNumTestContexts];
+
+ CHECK_EQ(0, CountGlobalContexts());
+
+ // Create a number of global contests which gets linked together.
+ for (int i = 0; i < kNumTestContexts; i++) {
+ ctx[i] = v8::Context::New();
+ CHECK_EQ(i + 1, CountGlobalContexts());
+
+ ctx[i]->Enter();
+ ctx[i]->Exit();
+ }
+
+ // Force compilation cache cleanup.
+ Heap::CollectAllGarbage(true);
+
+ // Dispose the global contexts one by one.
+ for (int i = 0; i < kNumTestContexts; i++) {
+ ctx[i].Dispose();
+ ctx[i].Clear();
+
+ // Scavenge treats these references as strong.
+ for (int j = 0; j < 10; j++) {
+ Heap::PerformScavenge();
+ CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
+ }
+
+ // Mark compact handles the weak references.
+ Heap::CollectAllGarbage(true);
+ CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
+ }
+
+ CHECK_EQ(0, CountGlobalContexts());
+}
+
+
+// Count the number of global contexts in the weak list of global contexts
+// causing a GC after the specified number of elements.
+static int CountGlobalContextsWithGC(int n) {
+ int count = 0;
+ Handle<Object> object(Heap::global_contexts_list());
+ while (!object->IsUndefined()) {
+ count++;
+ if (count == n) Heap::CollectAllGarbage(true);
+ object =
+ Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
+ }
+ return count;
+}
+
+
+TEST(TestInternalWeakListsTraverseWithGC) {
+ static const int kNumTestContexts = 10;
+
+ v8::HandleScope scope;
+ v8::Persistent<v8::Context> ctx[kNumTestContexts];
+
+ CHECK_EQ(0, CountGlobalContexts());
+
+ // Create an number of contexts and check the length of the weak list both
+ // with and without GCs while iterating the list.
+ for (int i = 0; i < kNumTestContexts; i++) {
+ ctx[i] = v8::Context::New();
+ CHECK_EQ(i + 1, CountGlobalContexts());
+ CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1));
+
+ ctx[i]->Enter();
+ ctx[i]->Exit();
+ }
+}