A simple test for map compact.

Review URL: http://codereview.chromium.org/543113

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3655 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
antonm@chromium.org 2010-01-19 16:34:37 +00:00
parent c8db42a351
commit 6619154580
4 changed files with 51 additions and 9 deletions

View File

@ -201,6 +201,11 @@ DEFINE_bool(canonicalize_object_literal_maps, true,
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")

View File

@ -3544,7 +3544,8 @@ bool Heap::Setup(bool create_heap_objects) {
// 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;

View File

@ -1753,8 +1753,11 @@ class FixedSpace : public PagedSpace {
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 @@ class MapSpace : public FixedSpace {
// 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 @@ class MapSpace : public FixedSpace {
}
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 @@ class MapSpace : public FixedSpace {
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")

View File

@ -207,6 +207,36 @@ TEST(MarkCompactCollector) {
}
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;
static int gc_ends = 0;