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