Revision: 8621
Author:   [email protected]
Date:     Wed Jul 13 00:22:45 2011
Log: Chang Heap::FreeQueuedChunks to prepare queued large chunks for StoreBuffer::Filter.

We split large chunks into separate smaller kPageSize aligned pieces to ensure that MemoryChunk::FromAnyPointerAddress would be able to find chunk containing slot even if the chunk was unlinked from the list of large chunks.

[email protected]
BUG=v8:1554

Review URL: http://codereview.chromium.org/7356005
http://code.google.com/p/v8/source/detail?r=8621

Modified:
 /branches/experimental/gc/src/heap.cc

=======================================
--- /branches/experimental/gc/src/heap.cc       Tue Jul 12 16:04:25 2011
+++ /branches/experimental/gc/src/heap.cc       Wed Jul 13 00:22:45 2011
@@ -5975,6 +5975,31 @@
   for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
     next = chunk->next_chunk();
     chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
+
+    if (chunk->owner()->identity() == LO_SPACE) {
+      // StoreBuffer::Filter relies on MemoryChunk::FromAnyPointerAddress.
+      // If FromAnyPointerAddress encounters a slot that belongs to a large
+      // chunk queued for deletion it will fail to find the chunk because
+ // it try to perform a search in the list of pages owned by of the large
+      // object space and queued chunks were detached from that list.
+ // To work around this we split large chunk into normal kPageSize aligned
+      // pieces and initialize owner field and flags of every piece.
+      // If FromAnyPointerAddress encounteres a slot that belongs to one of
+      // these smaller pieces it will treat it as a slot on a normal Page.
+      MemoryChunk* inner = MemoryChunk::FromAddress(
+          chunk->address() + Page::kPageSize);
+      MemoryChunk* inner_last = MemoryChunk::FromAddress(
+          chunk->address() + chunk->size() - 1);
+      while (inner <= inner_last) {
+        // Size of a large chunk is always a multiple of
+        // OS::AllocationAlignment() so there is always
+        // enough space for a fake MemoryChunk header.
+        inner->set_owner(lo_space());
+        inner->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
+        inner = MemoryChunk::FromAddress(
+            inner->address() + Page::kPageSize);
+      }
+    }
   }
   isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
   for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {

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

Reply via email to