Revision: 15146
Author:   [email protected]
Date:     Fri Jun 14 04:22:25 2013
Log: As a last resort try to allocate out of the smaller size size-class in
the free list allocator.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/17058002
http://code.google.com/p/v8/source/detail?r=15146

Modified:
 /branches/bleeding_edge/src/spaces.cc
 /branches/bleeding_edge/src/spaces.h

=======================================
--- /branches/bleeding_edge/src/spaces.cc       Thu Jun 13 10:03:57 2013
+++ /branches/bleeding_edge/src/spaces.cc       Fri Jun 14 04:22:25 2013
@@ -2118,13 +2118,13 @@

   while (node != NULL &&
          Page::FromAddress(node->address())->IsEvacuationCandidate()) {
-    available_ -= node->Size();
+    available_ -= reinterpret_cast<FreeSpace*>(node)->Size();
     node = node->next();
   }

   if (node != NULL) {
     set_top(node->next());
-    *node_size = node->Size();
+    *node_size = reinterpret_cast<FreeSpace*>(node)->Size();
     available_ -= *node_size;
   } else {
     set_top(NULL);
@@ -2136,6 +2136,18 @@

   return node;
 }
+
+
+FreeListNode* FreeListCategory::PickNodeFromList(int size_in_bytes,
+                                                 int *node_size) {
+  FreeListNode* node = PickNodeFromList(node_size);
+  if (node != NULL && *node_size < size_in_bytes) {
+    Free(node, *node_size);
+    *node_size = 0;
+    return NULL;
+  }
+  return node;
+}


 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) {
@@ -2202,11 +2214,6 @@
   // Insert other blocks at the head of a free list of the appropriate
   // magnitude.
   if (size_in_bytes <= kSmallListMax) {
-    ASSERT(!owner_->ConstantAllocationSize() ||
-        (owner_->identity() == MAP_SPACE && size_in_bytes >= Map::kSize) ||
- (owner_->identity() == CELL_SPACE && size_in_bytes >= Cell::kSize) ||
-        (owner_->identity() == PROPERTY_CELL_SPACE &&
-            size_in_bytes >= JSGlobalPropertyCell::kSize));
     small_list_.Free(node, size_in_bytes);
     page->add_available_in_small_free_list(size_in_bytes);
   } else if (size_in_bytes <= kMediumListMax) {
@@ -2229,13 +2236,13 @@
   FreeListNode* node = NULL;
   Page* page = NULL;

- if ((owner_->ConstantAllocationSize() && size_in_bytes <= kSmallListMax) ||
-      size_in_bytes <= kSmallAllocationMax) {
+  if (size_in_bytes <= kSmallAllocationMax) {
     node = small_list_.PickNodeFromList(node_size);
     if (node != NULL) {
       ASSERT(size_in_bytes <= *node_size);
       page = Page::FromAddress(node->address());
       page->add_available_in_small_free_list(-(*node_size));
+      ASSERT(IsVeryLong() || available() == SumFreeLists());
       return node;
     }
   }
@@ -2246,6 +2253,7 @@
       ASSERT(size_in_bytes <= *node_size);
       page = Page::FromAddress(node->address());
       page->add_available_in_medium_free_list(-(*node_size));
+      ASSERT(IsVeryLong() || available() == SumFreeLists());
       return node;
     }
   }
@@ -2256,6 +2264,7 @@
       ASSERT(size_in_bytes <= *node_size);
       page = Page::FromAddress(node->address());
       page->add_available_in_large_free_list(-(*node_size));
+      ASSERT(IsVeryLong() || available() == SumFreeLists());
       return node;
     }
   }
@@ -2298,10 +2307,37 @@
   if (huge_list_.top() == NULL) {
     huge_list_.set_end(NULL);
   }
-
   huge_list_.set_available(huge_list_available);
-  ASSERT(IsVeryLong() || available() == SumFreeLists());

+  if (node != NULL) {
+    ASSERT(IsVeryLong() || available() == SumFreeLists());
+    return node;
+  }
+
+  if (size_in_bytes <= kSmallListMax) {
+    node = small_list_.PickNodeFromList(size_in_bytes, node_size);
+    if (node != NULL) {
+      ASSERT(size_in_bytes <= *node_size);
+      page = Page::FromAddress(node->address());
+      page->add_available_in_small_free_list(-(*node_size));
+    }
+  } else if (size_in_bytes <= kMediumListMax) {
+    node = medium_list_.PickNodeFromList(size_in_bytes, node_size);
+    if (node != NULL) {
+      ASSERT(size_in_bytes <= *node_size);
+      page = Page::FromAddress(node->address());
+      page->add_available_in_medium_free_list(-(*node_size));
+    }
+  } else if (size_in_bytes <= kLargeListMax) {
+    node = large_list_.PickNodeFromList(size_in_bytes, node_size);
+    if (node != NULL) {
+      ASSERT(size_in_bytes <= *node_size);
+      page = Page::FromAddress(node->address());
+      page->add_available_in_large_free_list(-(*node_size));
+    }
+  }
+
+  ASSERT(IsVeryLong() || available() == SumFreeLists());
   return node;
 }

=======================================
--- /branches/bleeding_edge/src/spaces.h        Thu Jun 13 10:03:57 2013
+++ /branches/bleeding_edge/src/spaces.h        Fri Jun 14 04:22:25 2013
@@ -1454,6 +1454,7 @@
   void Free(FreeListNode* node, int size_in_bytes);

   FreeListNode* PickNodeFromList(int *node_size);
+  FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size);

   intptr_t EvictFreeListItemsInList(Page* p);

@@ -1819,11 +1820,6 @@
   inline int AreaSize() {
     return area_size_;
   }
-
-  bool ConstantAllocationSize() {
-    return identity() == MAP_SPACE || identity() == CELL_SPACE ||
-        identity() == PROPERTY_CELL_SPACE;
-  }

  protected:
   FreeList* free_list() { return &free_list_; }

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to