Hi Bert,

I did a quick look into this problem. It seems V8 currently can't handle
such big heaps:

0) Memory allocator and MarkCompact garbage collector encode certain things
in a special way so without major rewriting you can try to get at most
 ~1.8gb heap on x64.

1) Memory management code is full of integer overflows --- it uses int where
bigger type is required to handle big heap sizes. [I am attaching small
dirty patch to fix some of this overflows. with it you can grow heap almost
up to 1.8 gb heap]

2) GC pauses will be huge for huge heaps: mark-sweep will take at > 1 s,
mark-compact will take > 3s, scavenge throughput will also be degraded (it
needs to scan oldspaces for intergenerational pointers).

--
Vyacheslav Egorov


On Wed, Aug 25, 2010 at 10:36 AM, Bert Belder <[email protected]> wrote:

> On Aug 25, 9:57 am, Erik Corry <[email protected]> wrote:
> > Are you running the 64 bit version of V8?
>
> I think so. To eliminate other causes I did a fresh git clone from
> git://github.com/v8/v8.git, then:
>  scons arch=x64 sample=shell
>  ./shell --max_old_space_size=2000000000 test.js
>
> > file `which v8`
> ./shell: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
> dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not
> stripped
>
> - Bert
>
> --
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users
>

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
diff --git a/src/heap.cc b/src/heap.cc
index ff92384..015918a 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -64,11 +64,11 @@ MapSpace* Heap::map_space_ = NULL;
 CellSpace* Heap::cell_space_ = NULL;
 LargeObjectSpace* Heap::lo_space_ = NULL;
 
-static const int kMinimumPromotionLimit = 2*MB;
-static const int kMinimumAllocationLimit = 8*MB;
+static const intptr_t kMinimumPromotionLimit = 2*MB;
+static const intptr_t kMinimumAllocationLimit = 8*MB;
 
-int Heap::old_gen_promotion_limit_ = kMinimumPromotionLimit;
-int Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit;
+intptr_t Heap::old_gen_promotion_limit_ = kMinimumPromotionLimit;
+intptr_t Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit;
 
 int Heap::old_gen_exhausted_ = false;
 
@@ -83,9 +83,9 @@ int Heap::max_old_generation_size_ = 192*MB;
 int Heap::initial_semispace_size_ = 128*KB;
 size_t Heap::code_range_size_ = 0;
 #elif defined(V8_TARGET_ARCH_X64)
-int Heap::max_semispace_size_  = 16*MB;
-int Heap::max_old_generation_size_ = 1*GB;
-int Heap::initial_semispace_size_ = 1*MB;
+intptr_t Heap::max_semispace_size_  = 16*MB;
+intptr_t Heap::max_old_generation_size_ = 1.85*GB;
+intptr_t Heap::initial_semispace_size_ = 1*MB;
 size_t Heap::code_range_size_ = 512*MB;
 #else
 int Heap::max_semispace_size_  = 8*MB;
@@ -97,7 +97,7 @@ size_t Heap::code_range_size_ = 0;
 // The snapshot semispace size will be the default semispace size if
 // snapshotting is used and will be the requested semispace size as
 // set up by ConfigureHeap otherwise.
-int Heap::reserved_semispace_size_ = Heap::max_semispace_size_;
+intptr_t Heap::reserved_semispace_size_ = Heap::max_semispace_size_;
 
 List<Heap::GCPrologueCallbackPair> Heap::gc_prologue_callbacks_;
 List<Heap::GCEpilogueCallbackPair> Heap::gc_epilogue_callbacks_;
@@ -645,7 +645,7 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
 
     UpdateSurvivalRateTrend(start_new_space_size);
 
-    int old_gen_size = PromotedSpaceSize();
+    intptr_t old_gen_size = PromotedSpaceSize();
     old_gen_promotion_limit_ =
         old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
     old_gen_allocation_limit_ =
@@ -3996,7 +3996,7 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
 }
 
 
-int Heap::PromotedSpaceSize() {
+intptr_t Heap::PromotedSpaceSize() {
   return old_pointer_space_->Size()
       + old_data_space_->Size()
       + code_space_->Size()
diff --git a/src/heap.h b/src/heap.h
index 45fee17..d65fb31 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -243,13 +243,13 @@ class Heap : public AllStatic {
   // semi space.  The young generation consists of two semi spaces and
   // we reserve twice the amount needed for those in order to ensure
   // that new space can be aligned to its size.
-  static int MaxReserved() {
+  static intptr_t MaxReserved() {
     return 4 * reserved_semispace_size_ + max_old_generation_size_;
   }
-  static int MaxSemiSpaceSize() { return max_semispace_size_; }
-  static int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
-  static int InitialSemiSpaceSize() { return initial_semispace_size_; }
-  static int MaxOldGenerationSize() { return max_old_generation_size_; }
+  static intptr_t MaxSemiSpaceSize() { return max_semispace_size_; }
+  static intptr_t ReservedSemiSpaceSize() { return reserved_semispace_size_; }
+  static intptr_t InitialSemiSpaceSize() { return initial_semispace_size_; }
+  static intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
 
   // Returns the capacity of the heap in bytes w/o growing. Heap grows when
   // more spaces are needed until it reaches the limit.
@@ -1024,10 +1024,10 @@ class Heap : public AllStatic {
   static GCTracer* tracer() { return tracer_; }
 
  private:
-  static int reserved_semispace_size_;
-  static int max_semispace_size_;
-  static int initial_semispace_size_;
-  static int max_old_generation_size_;
+  static intptr_t reserved_semispace_size_;
+  static intptr_t max_semispace_size_;
+  static intptr_t initial_semispace_size_;
+  static intptr_t max_old_generation_size_;
   static size_t code_range_size_;
 
   // For keeping track of how much data has survived
@@ -1056,7 +1056,7 @@ class Heap : public AllStatic {
   static HeapState gc_state_;
 
   // Returns the size of object residing in non new spaces.
-  static int PromotedSpaceSize();
+  static intptr_t PromotedSpaceSize();
 
   // Returns the amount of external memory registered since last global gc.
   static int PromotedExternalMemorySize();
@@ -1091,12 +1091,12 @@ class Heap : public AllStatic {
   // Limit that triggers a global GC on the next (normally caused) GC.  This
   // is checked when we have already decided to do a GC to help determine
   // which collector to invoke.
-  static int old_gen_promotion_limit_;
+  static intptr_t old_gen_promotion_limit_;
 
   // Limit that triggers a global GC as soon as is reasonable.  This is
   // checked before expanding a paged space in the old generation and on
   // every allocation in large object space.
-  static int old_gen_allocation_limit_;
+  static intptr_t old_gen_allocation_limit_;
 
   // Limit on the amount of externally allocated memory allowed
   // between global GCs. If reached a global GC is forced.
diff --git a/src/spaces.cc b/src/spaces.cc
index 67adafd..6d6bcf6 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -264,9 +264,9 @@ void CodeRange::TearDown() {
 // -----------------------------------------------------------------------------
 // MemoryAllocator
 //
-int MemoryAllocator::capacity_   = 0;
-int MemoryAllocator::size_       = 0;
-int MemoryAllocator::size_executable_ = 0;
+intptr_t MemoryAllocator::capacity_   = 0;
+intptr_t MemoryAllocator::size_       = 0;
+intptr_t MemoryAllocator::size_executable_ = 0;
 
 VirtualMemory* MemoryAllocator::initial_chunk_ = NULL;
 
@@ -295,7 +295,7 @@ int MemoryAllocator::Pop() {
 
 void *executable_memory_histogram = NULL;
 
-bool MemoryAllocator::Setup(int capacity) {
+bool MemoryAllocator::Setup(intptr_t capacity) {
   capacity_ = RoundUp(capacity, Page::kPageSize);
 
   // Over-estimate the size of chunks_ array.  It assumes the expansion of old
diff --git a/src/spaces.h b/src/spaces.h
index a6b8ea4..c0f76b9 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -489,7 +489,7 @@ class MemoryAllocator : public AllStatic {
  public:
   // Initializes its internal bookkeeping structures.
   // Max capacity of the total space.
-  static bool Setup(int max_capacity);
+  static bool Setup(intptr_t max_capacity);
 
   // Deletes valid chunks.
   static void TearDown();
@@ -636,12 +636,12 @@ class MemoryAllocator : public AllStatic {
 
  private:
   // Maximum space size in bytes.
-  static int capacity_;
+  static intptr_t capacity_;
 
   // Allocated space size in bytes.
-  static int size_;
+  static intptr_t size_;
   // Allocated executable space size in bytes.
-  static int size_executable_;
+  static intptr_t size_executable_;
 
   // The initial chunk of virtual memory.
   static VirtualMemory* initial_chunk_;

Reply via email to