Fix counting of scanned bytes in incremental marking step for large object.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 May 2013 11:13:59 +0000 (11:13 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 May 2013 11:13:59 +0000 (11:13 +0000)
R=mstarzinger@chromium.org
BUG=241815

Review URL: https://chromiumcodereview.appspot.com/15745004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14877 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/incremental-marking.cc
src/incremental-marking.h
test/cctest/test-heap.cc

index bacbb93ad2e8cb6a335c577e8ccf69ade8c82d63..e19d6e28f69f9141b3d47756bcf2d3129a9a6eaf 100644 (file)
@@ -54,7 +54,8 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
       should_hurry_(false),
       marking_speed_(0),
       allocated_(0),
-      no_marking_scope_depth_(0) {
+      no_marking_scope_depth_(0),
+      unscanned_bytes_of_large_object_(0) {
 }
 
 
@@ -241,6 +242,7 @@ class IncrementalMarkingMarkingVisitor
                              chunk->progress_bar());
       int end_offset = Min(object_size,
                            start_offset + kProgressBarScanningChunk);
+      int already_scanned_offset = start_offset;
       bool scan_until_end = false;
       do {
         VisitPointersWithAnchor(heap,
@@ -254,6 +256,8 @@ class IncrementalMarkingMarkingVisitor
       chunk->set_progress_bar(start_offset);
       if (start_offset < object_size) {
         heap->incremental_marking()->marking_deque()->UnshiftGrey(object);
+        heap->incremental_marking()->NotifyIncompleteScanOfObject(
+            object_size - (start_offset - already_scanned_offset));
       }
     } else {
       FixedArrayVisitor::Visit(map, object);
@@ -739,8 +743,9 @@ void IncrementalMarking::ProcessMarkingDeque(intptr_t bytes_to_process) {
     if (map == filler_map) continue;
 
     int size = obj->SizeFromMap(map);
-    bytes_to_process -= size;
+    unscanned_bytes_of_large_object_ = 0;
     VisitObject(map, obj, size);
+    bytes_to_process -= (size - unscanned_bytes_of_large_object_);
   }
 }
 
index 47d5a518bf841076c805b27c5acc22719ab3f2b8..d47c300ef3f97893e3f018c0aab3a20c76856da9 100644 (file)
@@ -220,6 +220,10 @@ class IncrementalMarking {
 
   void UncommitMarkingDeque();
 
+  void NotifyIncompleteScanOfObject(int unscanned_bytes) {
+    unscanned_bytes_of_large_object_ = unscanned_bytes;
+  }
+
  private:
   int64_t SpaceLeftInOldSpace();
 
@@ -274,6 +278,8 @@ class IncrementalMarking {
 
   int no_marking_scope_depth_;
 
+  int unscanned_bytes_of_large_object_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking);
 };
 
index 1122fa98cb2dd47a0d84b86912befc20aa63dfaf..1f1b357854782efd400ed0025221c536bcb0c326 100644 (file)
@@ -3107,3 +3107,19 @@ TEST(DeferredHandles) {
   isolate->handle_scope_implementer()->Iterate(&visitor);
   deferred.Detach();
 }
+
+
+TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  CompileRun("function f(n) {"
+             "    var a = new Array(n);"
+             "    for (var i = 0; i < n; i += 100) a[i] = i;"
+             "};"
+             "f(10 * 1024 * 1024);");
+  IncrementalMarking* marking = HEAP->incremental_marking();
+  if (marking->IsStopped()) marking->Start();
+  // This big step should be sufficient to mark the whole array.
+  marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+  ASSERT(marking->IsComplete());
+}