Reviewers: Vyacheslav Egorov,

Description:
Make heap size estimation more accurate.

This improves the heap size estimation by not counting lazy swept pages
as completely allocated but use their live bytes counter instead.

[email protected]
BUG=v8:1892
TEST=cctest/test-heap/TestSizeOfObjects


Please review this at http://codereview.chromium.org/9173001/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/spaces.h
  M src/spaces.cc
  M test/cctest/test-heap.cc


Index: src/spaces.cc
diff --git a/src/spaces.cc b/src/spaces.cc
index ebd3e6519208d9103a1b9d5e5bd975442d14c7fb..1bcea22b8e1850116c44ac91f384cad426888898 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -749,6 +749,20 @@ int PagedSpace::CountTotalPages() {
 }


+intptr_t PagedSpace::SizeOfObjectsSlow() {
+  PageIterator it(this);
+  intptr_t size_of_objects = accounting_stats_.Size();
+  while (it.has_next()) {
+    Page* p = it.next();
+    if (!p->WasSwept()) {
+      size_of_objects -= Page::kObjectAreaSize;
+      size_of_objects += p->LiveBytes();
+    }
+  }
+  return size_of_objects - (limit() - top());
+}
+
+
 void PagedSpace::ReleasePage(Page* page) {
   ASSERT(page->LiveBytes() == 0);

Index: src/spaces.h
diff --git a/src/spaces.h b/src/spaces.h
index 41bfec90f142797bdc295d622505ee963c6b05c6..60432e39cf7c30a55da8131e52fba42350705b7e 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1469,9 +1469,16 @@ class PagedSpace : public Space {
   // linear allocation area (between top and limit) are also counted here.
   virtual intptr_t Size() { return accounting_stats_.Size(); }

-  // As size, but the bytes in the current linear allocation area are not
-  // included.
-  virtual intptr_t SizeOfObjects() { return Size() - (limit() - top()); }
+ // As size, but the bytes in lazily swept pages are estimated and the bytes
+  // in the current linear allocation area are not included.
+  intptr_t SizeOfObjectsSlow();
+  virtual intptr_t SizeOfObjects() {
+    if (IsSweepingComplete()) {
+      return Size() - (limit() - top());
+    } else {
+      return SizeOfObjectsSlow();
+    }
+  }

// Wasted bytes in this space. These are just the bytes that were thrown away
   // due to being too small to use for allocation.  They do not include the
@@ -1479,9 +1486,7 @@ class PagedSpace : public Space {
   virtual intptr_t Waste() { return accounting_stats_.Waste(); }

   // Returns the allocation pointer in this space.
-  Address top() {
-    return allocation_info_.top;
-  }
+  Address top() { return allocation_info_.top; }
   Address limit() { return allocation_info_.limit; }

// Allocate the requested number of bytes in the space if possible, return a
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 42b5789d4d02f17f520af87c6a27c148e2b59dbc..da64ba9cc5c85a2a8d61efa77e93909a5cc4f77d 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1187,6 +1187,35 @@ TEST(TestInternalWeakListsTraverseWithGC) {
 }


+TEST(TestSizeOfObjects) {
+  v8::V8::Initialize();
+
+  // Get initial heap size after a full GC, which should return after
+  // sweeping finished completely.
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
+  intptr_t initial_size = HEAP->SizeOfObjects();
+
+  {
+    // Allocate objects on two different old-space pages so that lazy
+    // sweeping kicks in for subsequent GC runs.
+    AlwaysAllocateScope always_allocate;
+    intptr_t filler_size = FixedArray::SizeFor(8192);
+    for (int i = 1; i <= 100; i++) {
+      HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
+      CHECK_EQ(initial_size + i * filler_size, HEAP->SizeOfObjects());
+    }
+  }
+
+  // The heap size should go back to initial size after a  full GC, even
+  // though sweeping didn't finish yet (with a delta of about 512 words).
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
+  CHECK_LE(HEAP->SizeOfObjects(), initial_size);
+  CHECK_GT(HEAP->SizeOfObjects(), initial_size - 512 * kPointerSize);
+}
+
+
 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
   InitializeVM();
   HEAP->EnsureHeapIsIterable();


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to