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:
parent
c8db42a351
commit
6619154580
@ -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")
|
||||
|
@ -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;
|
||||
|
22
src/spaces.h
22
src/spaces.h
@ -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")
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user