Reviewers: Michael Starzinger,

Description:
Reduce initial boot-up memory use.  This is an other attempt at what
http://codereview.chromium.org/9179012 was trying to achieve.  This
time I am going for 80% of the benefit with around 5% of the complexity.

It works by reducing the size of the first page in each space.  Unlike the
previous change there is no attempt to grow pages, we just allocate more
full-sized pages when we need more memory. For this reason the first pages are
not quite as small (compare
http://codereview.chromium.org/9179012/diff/1/src/snapshot.h with the changes in spaces.cc in this cl): We want to be able to do a little bit of allocation
before we have to add a full-sized page to the space.

Please review this at https://chromiumcodereview.appspot.com/9950048/

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

Affected files:
  M     src/spaces-inl.h
  M     src/spaces.h
  M     src/spaces.cc
  M     test/cctest/test-mark-compact.cc
  M     test/cctest/test-spaces.cc


Index: src/spaces-inl.h
===================================================================
--- src/spaces-inl.h    (revision 11201)
+++ src/spaces-inl.h    (working copy)
@@ -164,7 +164,7 @@
                        Executability executable,
                        PagedSpace* owner) {
   Page* page = reinterpret_cast<Page*>(chunk);
-  ASSERT(chunk->size() == static_cast<size_t>(kPageSize));
+  ASSERT(chunk->size() <= static_cast<size_t>(kPageSize));
   ASSERT(chunk->owner() == owner);
   owner->IncreaseCapacity(page->area_size());
   owner->Free(page->area_start(), page->area_size());
Index: src/spaces.cc
===================================================================
--- src/spaces.cc       (revision 11201)
+++ src/spaces.cc       (working copy)
@@ -565,11 +565,10 @@
 }


-Page* MemoryAllocator::AllocatePage(PagedSpace* owner,
+Page* MemoryAllocator::AllocatePage(intptr_t size,
+                                    PagedSpace* owner,
                                     Executability executable) {
-  MemoryChunk* chunk = AllocateChunk(owner->AreaSize(),
-                                     executable,
-                                     owner);
+  MemoryChunk* chunk = AllocateChunk(size, executable, owner);

   if (chunk == NULL) return NULL;

@@ -833,7 +832,6 @@

 bool PagedSpace::CanExpand() {
   ASSERT(max_capacity_ % AreaSize() == 0);
-  ASSERT(Capacity() % AreaSize() == 0);

   if (Capacity() == max_capacity_) return false;

@@ -848,8 +846,14 @@
 bool PagedSpace::Expand() {
   if (!CanExpand()) return false;

-  Page* p = heap()->isolate()->memory_allocator()->
-      AllocatePage(this, executable());
+  intptr_t size = AreaSize();
+
+  if (anchor_.next_page() == &anchor_) {
+    size = SizeOfFirstPage();
+  }
+
+  Page* p = heap()->isolate()->memory_allocator()->AllocatePage(
+      size, this, executable());
   if (p == NULL) return false;

   ASSERT(Capacity() <= max_capacity_);
@@ -860,6 +864,39 @@
 }


+intptr_t PagedSpace::SizeOfFirstPage() {
+  int size = 0;
+  void* dummy;
+  switch (identity()) {
+    case OLD_POINTER_SPACE:
+      size = 64 * sizeof(dummy) * KB;
+      break;
+    case OLD_DATA_SPACE:
+      size = 192 * KB;
+      break;
+    case MAP_SPACE:
+      size = 128 * KB;
+      break;
+    case CELL_SPACE:
+      size = 96 * KB;
+      break;
+    case CODE_SPACE:
+      if (sizeof(dummy) == 8) {
+ // On x64 we allocate code pages in a special way (from the reserved
+        // 2Byte area). That part of the code is not yet upgraded to handle
+        // small pages.
+        size = AreaSize();
+      } else {
+        size = 384 * KB;
+      }
+      break;
+    default:
+      UNREACHABLE();
+  }
+  return Min(size, AreaSize());
+}
+
+
 int PagedSpace::CountTotalPages() {
   PageIterator it(this);
   int count = 0;
@@ -903,7 +940,6 @@
   }

   ASSERT(Capacity() > 0);
-  ASSERT(Capacity() % AreaSize() == 0);
   accounting_stats_.ShrinkSpace(AreaSize());
 }

@@ -1042,6 +1078,7 @@
   if (!to_space_.Commit()) {
     return false;
   }
+  ASSERT(!from_space_.is_committed());  // No need to use memory yet.

   start_ = chunk_base_;
   address_mask_ = ~(2 * reserved_semispace_capacity - 1);
Index: src/spaces.h
===================================================================
--- src/spaces.h        (revision 11201)
+++ src/spaces.h        (working copy)
@@ -637,8 +637,10 @@
   friend class MemoryAllocator;
 };

+
 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize);

+
// ----------------------------------------------------------------------------- // A page is a memory chunk of a size 1MB. Large object pages may be larger.
 //
@@ -950,7 +952,8 @@

   void TearDown();

-  Page* AllocatePage(PagedSpace* owner, Executability executable);
+  Page* AllocatePage(
+      intptr_t size, PagedSpace* owner, Executability executable);

   LargePage* AllocateLargePage(intptr_t object_size,
                                       Executability executable,
@@ -1625,6 +1628,8 @@
   // Maximum capacity of this space.
   intptr_t max_capacity_;

+  intptr_t SizeOfFirstPage();
+
   // Accounting information for this space.
   AllocationStats accounting_stats_;

Index: test/cctest/test-mark-compact.cc
===================================================================
--- test/cctest/test-mark-compact.cc    (revision 11201)
+++ test/cctest/test-mark-compact.cc    (working copy)
@@ -534,15 +534,15 @@
     intptr_t booted_memory = MemoryInUse();
     if (sizeof(initial_memory) == 8) {
       if (v8::internal::Snapshot::IsEnabled()) {
-        CHECK_LE(booted_memory - initial_memory, 6686 * 1024);  // 6476.
+        CHECK_LE(booted_memory - initial_memory, 3500 * 1024);  // 3396.
       } else {
-        CHECK_LE(booted_memory - initial_memory, 6809 * 1024);  // 6628.
+        CHECK_LE(booted_memory - initial_memory, 3500 * 1024);  // 3432.
       }
     } else {
       if (v8::internal::Snapshot::IsEnabled()) {
-        CHECK_LE(booted_memory - initial_memory, 6532 * 1024);  // 6388.
+        CHECK_LE(booted_memory - initial_memory, 2600 * 1024);  // 2484.
       } else {
-        CHECK_LE(booted_memory - initial_memory, 6940 * 1024);  // 6456
+        CHECK_LE(booted_memory - initial_memory, 2950 * 1024);  // 2844
       }
     }
   }
Index: test/cctest/test-spaces.cc
===================================================================
--- test/cctest/test-spaces.cc  (revision 11201)
+++ test/cctest/test-spaces.cc  (working copy)
@@ -140,8 +140,8 @@
                        heap->MaxReserved(),
                        OLD_POINTER_SPACE,
                        NOT_EXECUTABLE);
-  Page* first_page =
-      memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE);
+  Page* first_page = memory_allocator->AllocatePage(
+      faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE);

   first_page->InsertAfter(faked_space.anchor()->prev_page());
   CHECK(first_page->is_valid());
@@ -153,8 +153,8 @@
   }

   // Again, we should get n or n - 1 pages.
-  Page* other =
-      memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE);
+  Page* other = memory_allocator->AllocatePage(
+      faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE);
   CHECK(other->is_valid());
   total_pages++;
   other->InsertAfter(first_page);


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

Reply via email to