Revision: 3655
Author: [email protected]
Date: Tue Jan 19 08:34:37 2010
Log: A simple test for map compact.

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

Modified:
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/spaces.h
 /branches/bleeding_edge/test/cctest/test-mark-compact.cc

=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Mon Jan 18 08:04:25 2010
+++ /branches/bleeding_edge/src/flag-definitions.h      Tue Jan 19 08:34:37 2010
@@ -201,6 +201,11 @@
 DEFINE_bool(use_big_map_space, true,
             "Use big map space, but don't compact if it grew too big.")

+DEFINE_int(max_map_space_pages, MapSpace::kMaxMapPageIndex - 1,
+ "Maximum number of pages in map space which still allows to encode " + "forwarding pointers. That's actually a constant, but it's useful "
+           "to control it with a flag for better testing.")
+
 // mksnapshot.cc
 DEFINE_bool(h, false, "print this message")
 DEFINE_bool(new_snapshot, true, "use new snapshot implementation")
=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Jan 14 06:46:31 2010
+++ /branches/bleeding_edge/src/heap.cc Tue Jan 19 08:34:37 2010
@@ -3544,7 +3544,8 @@
   // Initialize map space.
   map_space_ = new MapSpace(FLAG_use_big_map_space
       ? max_old_generation_size_
-      : (MapSpace::kMaxMapPageIndex + 1) * Page::kPageSize,
+      : MapSpace::kMaxMapPageIndex * Page::kPageSize,
+      FLAG_max_map_space_pages,
       MAP_SPACE);
   if (map_space_ == NULL) return false;
   if (!map_space_->Setup(NULL, 0)) return false;
=======================================
--- /branches/bleeding_edge/src/spaces.h        Thu Jan 14 04:51:38 2010
+++ /branches/bleeding_edge/src/spaces.h        Tue Jan 19 08:34:37 2010
@@ -1753,8 +1753,11 @@
 class MapSpace : public FixedSpace {
  public:
   // Creates a map space object with a maximum capacity.
-  MapSpace(int max_capacity, AllocationSpace id)
-      : FixedSpace(max_capacity, id, Map::kSize, "map") {}
+  MapSpace(int max_capacity, int max_map_space_pages, AllocationSpace id)
+      : FixedSpace(max_capacity, id, Map::kSize, "map"),
+        max_map_space_pages_(max_map_space_pages) {
+    ASSERT(max_map_space_pages < kMaxMapPageIndex);
+  }

   // Prepares for a mark-compact GC.
   virtual void PrepareForMarkCompact(bool will_compact);
@@ -1762,8 +1765,7 @@
   // Given an index, returns the page address.
Address PageAddress(int page_index) { return page_addresses_[page_index]; }

-  // Constants.
- static const int kMaxMapPageIndex = (1 << MapWord::kMapPageIndexBits) - 1;
+  static const int kMaxMapPageIndex = 1 << MapWord::kMapPageIndexBits;

   // Are map pointers encodable into map word?
   bool MapPointersEncodable() {
@@ -1773,13 +1775,13 @@
     }
     int n_of_pages = Capacity() / Page::kObjectAreaSize;
     ASSERT(n_of_pages == CountTotalPages());
-    return n_of_pages <= kMaxMapPageIndex;
+    return n_of_pages <= max_map_space_pages_;
   }

   // Should be called after forced sweep to find out if map space needs
   // compaction.
   bool NeedsCompaction(int live_maps) {
-    return !MapPointersEncodable() && live_maps <= kCompactionThreshold;
+    return !MapPointersEncodable() && live_maps <= CompactionThreshold();
   }

   Address TopAfterCompaction(int live_maps) {
@@ -1838,10 +1840,14 @@
   static const int kMapsPerPage = Page::kObjectAreaSize / Map::kSize;

   // Do map space compaction if there is a page gap.
- static const int kCompactionThreshold = kMapsPerPage * (kMaxMapPageIndex - 1);
+  int CompactionThreshold() {
+    return kMapsPerPage * (max_map_space_pages_ - 1);
+  }
+
+  const int max_map_space_pages_;

   // An array of page start address in a map space.
-  Address page_addresses_[kMaxMapPageIndex + 1];
+  Address page_addresses_[kMaxMapPageIndex];

  public:
   TRACK_MEMORY("MapSpace")
=======================================
--- /branches/bleeding_edge/test/cctest/test-mark-compact.cc Wed Oct 21 08:03:34 2009 +++ /branches/bleeding_edge/test/cctest/test-mark-compact.cc Tue Jan 19 08:34:37 2010
@@ -205,6 +205,36 @@
   prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot"));
   CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23));
 }
+
+
+static Handle<Map> CreateMap() {
+  return Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+}
+
+
+TEST(MapCompact) {
+  FLAG_max_map_space_pages = 16;
+  InitializeVM();
+
+  {
+    v8::HandleScope sc;
+    // keep allocating maps while pointers are still encodable and thus
+    // mark compact is permitted.
+    Handle<JSObject> root = Factory::NewJSObjectFromMap(CreateMap());
+    do {
+      Handle<Map> map = CreateMap();
+      map->set_prototype(*root);
+      root = Factory::NewJSObjectFromMap(map);
+    } while (Heap::map_space()->MapPointersEncodable());
+  }
+  // Now, as we don't have any handles to just allocated maps, we should
+  // be able to trigger map compaction.
+  // To give an additional chance to fail, try to force compaction which
+  // should be impossible right now.
+  Heap::CollectAllGarbage(true);
+  // And now map pointers should be encodable again.
+  CHECK(Heap::map_space()->MapPointersEncodable());
+}


 static int gc_starts = 0;
-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to