Reviewers: Erik Corry,

Description:
Exponentially increase incremental marking factor each 512 steps.

Track inlined new space allocations and do steps based on the amount of
allocated data.

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

SVN Base: https://v8.googlecode.com/svn/branches/experimental/gc

Affected files:
  M src/incremental-marking.h
  M src/incremental-marking.cc
  M src/spaces-inl.h
  M src/spaces.h
  M src/spaces.cc


Index: src/incremental-marking.cc
diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc
index b10ae9c180dcac0055ef0642594c446a56d41213..128d23ae0f79c98a25d4da326f9a77de1b775bec 100644
--- a/src/incremental-marking.cc
+++ b/src/incremental-marking.cc
@@ -39,6 +39,7 @@ MarkingStack IncrementalMarking::marking_stack_;

 double IncrementalMarking::steps_took_ = 0;
 int IncrementalMarking::steps_count_ = 0;
+intptr_t IncrementalMarking::allocation_marking_factor_ = 0;

 static intptr_t allocated = 0;

@@ -221,6 +222,8 @@ void IncrementalMarking::Start() {
   VerifyMarkbitsAreClean();
 #endif

+  Heap::new_space()->LowerInlineAllocationLimit(kAllocatedThreshold);
+
   // Mark strong roots grey.
   IncrementalMarkingRootMarkingVisitor visitor;
   Heap::IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
@@ -332,7 +335,7 @@ void IncrementalMarking::Step(intptr_t allocated_bytes) {
         start = OS::TimeCurrentMillis();
       }

-      intptr_t bytes_to_process = allocated * kAllocationMarkingFactor;
+      intptr_t bytes_to_process = allocated * allocation_marking_factor_;
       int count = 0;

       Map* filler_map = Heap::one_pointer_filler_map();
@@ -360,7 +363,12 @@ void IncrementalMarking::Step(intptr_t allocated_bytes) {
       if (FLAG_trace_incremental_marking || FLAG_trace_gc) {
         double end = OS::TimeCurrentMillis();
         steps_took_ += (end - start);
-        steps_count_++;
+      }
+
+      steps_count_++;
+
+      if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) {
+        allocation_marking_factor_ *= kAllocationMarkingFactorSpeedup;
       }
     }
   }
Index: src/incremental-marking.h
diff --git a/src/incremental-marking.h b/src/incremental-marking.h
index 1b2c4ac1a232d372057332b2406738ab513a76b3..0e0619a54b3c60d509cd7e2707a04c8c89b7febb 100644
--- a/src/incremental-marking.h
+++ b/src/incremental-marking.h
@@ -69,7 +69,9 @@ class IncrementalMarking : public AllStatic {
   static void MarkingComplete();

   static const intptr_t kAllocatedThreshold = 1024;
-  static const intptr_t kAllocationMarkingFactor = 8;
+  static const intptr_t kInitialAllocationMarkingFactor = 8;
+  static const intptr_t kAllocationMarkingFactorSpeedupInterval = 512;
+  static const intptr_t kAllocationMarkingFactorSpeedup = 2;

   static void Step(intptr_t allocated);

@@ -218,6 +220,7 @@ class IncrementalMarking : public AllStatic {
   static void ResetStepCounters() {
     steps_count_ = 0;
     steps_took_ = 0;
+    allocation_marking_factor_ = kInitialAllocationMarkingFactor;
   }


@@ -227,6 +230,7 @@ class IncrementalMarking : public AllStatic {
   static int steps_count_;
   static double steps_took_;

+  static intptr_t allocation_marking_factor_;
 };

 } }  // namespace v8::internal
Index: src/spaces-inl.h
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index 6bc1b4f71a68028a8c4766de096846e41c1601de..91382c1397829023b5d15879c30d39677df61535 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -203,22 +203,26 @@ MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) { // -----------------------------------------------------------------------------
 // NewSpace

-MaybeObject* NewSpace::AllocateRawInternal(int size_in_bytes,
-                                           AllocationInfo* alloc_info) {
-  Address new_top = alloc_info->top + size_in_bytes;
-  if (new_top > alloc_info->limit) return Failure::RetryAfterGC();
+MaybeObject* NewSpace::AllocateRawInternal(int size_in_bytes) {
+  Address new_top = allocation_info_.top + size_in_bytes;
+  if (new_top > allocation_info_.limit) {
+    Address high = to_space_.high();
+    if (allocation_info_.limit < high) {
+      allocation_info_.limit = Min(
+          allocation_info_.limit + inline_alloction_limit_step_,
+          high);
+      return AllocateRawInternal(size_in_bytes);
+    }
+    return Failure::RetryAfterGC();
+  }

-  Object* obj = HeapObject::FromAddress(alloc_info->top);
-  alloc_info->top = new_top;
-#ifdef DEBUG
-  SemiSpace* space =
-      (alloc_info == &allocation_info_) ? &to_space_ : &from_space_;
-  ASSERT(space->low() <= alloc_info->top
-         && alloc_info->top <= space->high()
-         && alloc_info->limit == space->high());
-#endif
+  Object* obj = HeapObject::FromAddress(allocation_info_.top);
+  allocation_info_.top = new_top;
+  ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);

-  IncrementalMarking::Step(size_in_bytes);
+  int bytes_allocated = new_top - top_on_previous_step_;
+  IncrementalMarking::Step(bytes_allocated);
+  top_on_previous_step_ = new_top;

   return obj;
 }
Index: src/spaces.cc
diff --git a/src/spaces.cc b/src/spaces.cc
index cc19529d02626779a550129604fc0da343ca3c81..b02fe5dd469d2591d997945c1d246ede910fe2d7 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -35,13 +35,6 @@
 namespace v8 {
 namespace internal {

-// For contiguous spaces, top should be in the space (or at the end) and limit
-// should be the end of the space.
-#define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
-  ASSERT((space).low() <= (info).top                  \
-         && (info).top <= (space).high()              \
-         && (info).limit == (space).high())
-
// ----------------------------------------------------------------------------
 // HeapObjectIterator

@@ -848,10 +841,8 @@ bool NewSpace::Setup(int maximum_semispace_capacity) {
   object_mask_ = address_mask_ | kHeapObjectTagMask;
   object_expected_ = reinterpret_cast<uintptr_t>(start_) | kHeapObjectTag;

-  allocation_info_.top = to_space_.low();
-  allocation_info_.limit = to_space_.high();
+  ResetAllocationInfo();

-  ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
   return true;
 }

Index: src/spaces.h
diff --git a/src/spaces.h b/src/spaces.h
index b0a65bc49c6b2a53f742b8e19156ee0b20602b44..f2c5f0b74e3cbdebe3bbb15cdc402413f7bc90c5 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1631,12 +1631,20 @@ class NewSpace : public Space {
   Address* allocation_limit_address() { return &allocation_info_.limit; }

   MUST_USE_RESULT MaybeObject* AllocateRaw(int size_in_bytes) {
-    return AllocateRawInternal(size_in_bytes, &allocation_info_);
+    return AllocateRawInternal(size_in_bytes);
   }

   // Reset the allocation pointer to the beginning of the active semispace.
   void ResetAllocationInfo();

+  void LowerInlineAllocationLimit(intptr_t step) {
+    inline_alloction_limit_step_ = step;
+    allocation_info_.limit = Min(
+        allocation_info_.top + inline_alloction_limit_step_,
+        allocation_info_.limit);
+    top_on_previous_step_ = allocation_info_.top;
+  }
+
   // Get the extent of the inactive semispace (for use as a marking stack).
   Address FromSpaceLow() { return from_space_.low(); }
   Address FromSpaceHigh() { return from_space_.high(); }
@@ -1727,15 +1735,21 @@ class NewSpace : public Space {
   // mark-compact collection.
   AllocationInfo allocation_info_;

+  // When incremental marking is active we will set allocation_info_.limit
+  // to be lower than actual limit and then will gradually increase it
+  // in steps to guarantee that we do incremental marking steps even
+  // when all allocation is performed from inlined generated code.
+  intptr_t inline_alloction_limit_step_;
+
+  Address top_on_previous_step_;
+
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   HistogramInfo* allocated_histogram_;
   HistogramInfo* promoted_histogram_;
 #endif

-  // Implementation of AllocateRaw and MCAllocateRaw.
-  MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(
-      int size_in_bytes,
-      AllocationInfo* alloc_info);
+  // Implementation of AllocateRaw.
+ MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(int size_in_bytes);

   friend class SemiSpaceIterator;

@@ -1772,6 +1786,14 @@ class OldSpace : public PagedSpace {
 };


+// For contiguous spaces, top should be in the space (or at the end) and limit
+// should be the end of the space.
+#define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
+  ASSERT((space).low() <= (info).top                  \
+         && (info).top <= (space).high()              \
+         && (info).limit <= (space).high())
+
+
// -----------------------------------------------------------------------------
 // Old space for objects of a fixed size



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

Reply via email to