Revision: 11203
Author:   [email protected]
Date:     Mon Apr  2 01:32:31 2012
Log: 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.
Review URL: https://chromiumcodereview.appspot.com/9950048
http://code.google.com/p/v8/source/detail?r=11203

Modified:
 /branches/bleeding_edge/src/spaces-inl.h
 /branches/bleeding_edge/src/spaces.cc
 /branches/bleeding_edge/src/spaces.h
 /branches/bleeding_edge/test/cctest/test-mark-compact.cc
 /branches/bleeding_edge/test/cctest/test-spaces.cc

=======================================
--- /branches/bleeding_edge/src/spaces-inl.h    Thu Feb 23 04:11:24 2012
+++ /branches/bleeding_edge/src/spaces-inl.h    Mon Apr  2 01:32:31 2012
@@ -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());
=======================================
--- /branches/bleeding_edge/src/spaces.cc       Tue Mar 20 01:12:31 2012
+++ /branches/bleeding_edge/src/spaces.cc       Mon Apr  2 01:32:31 2012
@@ -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;

@@ -578,8 +577,8 @@


 LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size,
-                                              Executability executable,
-                                              Space* owner) {
+                                              Space* owner,
+                                              Executability executable) {
   MemoryChunk* chunk = AllocateChunk(object_size, executable, owner);
   if (chunk == NULL) return NULL;
   return LargePage::Initialize(isolate_->heap(), chunk);
@@ -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_);
@@ -858,6 +862,38 @@

   return true;
 }
+
+
+intptr_t PagedSpace::SizeOfFirstPage() {
+  int size = 0;
+  switch (identity()) {
+    case OLD_POINTER_SPACE:
+      size = 64 * kPointerSize * 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 (kPointerSize == 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() {
@@ -903,7 +939,6 @@
   }

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

@@ -1042,6 +1077,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);
@@ -2581,7 +2617,7 @@
   }

   LargePage* page = heap()->isolate()->memory_allocator()->
-      AllocateLargePage(object_size, executable, this);
+      AllocateLargePage(object_size, this, executable);
   if (page == NULL) return Failure::RetryAfterGC(identity());
   ASSERT(page->area_size() >= object_size);

=======================================
--- /branches/bleeding_edge/src/spaces.h        Mon Mar 19 05:08:20 2012
+++ /branches/bleeding_edge/src/spaces.h        Mon Apr  2 01:32:31 2012
@@ -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,11 +952,11 @@

   void TearDown();

-  Page* AllocatePage(PagedSpace* owner, Executability executable);
-
-  LargePage* AllocateLargePage(intptr_t object_size,
-                                      Executability executable,
-                                      Space* owner);
+  Page* AllocatePage(
+      intptr_t size, PagedSpace* owner, Executability executable);
+
+  LargePage* AllocateLargePage(
+      intptr_t object_size, Space* owner, Executability executable);

   void Free(MemoryChunk* chunk);

@@ -1625,6 +1627,8 @@
   // Maximum capacity of this space.
   intptr_t max_capacity_;

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

=======================================
--- /branches/bleeding_edge/test/cctest/test-mark-compact.cc Thu Feb 23 06:36:11 2012 +++ /branches/bleeding_edge/test/cctest/test-mark-compact.cc Mon Apr 2 01:32:31 2012
@@ -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
       }
     }
   }
=======================================
--- /branches/bleeding_edge/test/cctest/test-spaces.cc Thu Feb 23 04:11:24 2012 +++ /branches/bleeding_edge/test/cctest/test-spaces.cc Mon Apr 2 01:32:31 2012
@@ -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