Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Unified Diff: src/mark-compact.cc

Issue 435003: Patch for allowing several V8 instances in process:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 3427)
+++ src/mark-compact.cc (working copy)
@@ -38,38 +38,15 @@
// -------------------------------------------------------------------------
// MarkCompactCollector
-
-bool MarkCompactCollector::force_compaction_ = false;
-bool MarkCompactCollector::compacting_collection_ = false;
-bool MarkCompactCollector::compact_on_next_gc_ = false;
-
-int MarkCompactCollector::previous_marked_count_ = 0;
-GCTracer* MarkCompactCollector::tracer_ = NULL;
-
-
-#ifdef DEBUG
-MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE;
-
-// Counters used for debugging the marking phase of mark-compact or mark-sweep
-// collection.
-int MarkCompactCollector::live_bytes_ = 0;
-int MarkCompactCollector::live_young_objects_ = 0;
-int MarkCompactCollector::live_old_data_objects_ = 0;
-int MarkCompactCollector::live_old_pointer_objects_ = 0;
-int MarkCompactCollector::live_code_objects_ = 0;
-int MarkCompactCollector::live_map_objects_ = 0;
-int MarkCompactCollector::live_cell_objects_ = 0;
-int MarkCompactCollector::live_lo_objects_ = 0;
-#endif
-
void MarkCompactCollector::CollectGarbage() {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
// Make sure that Prepare() has been called. The individual steps below will
// update the state as they proceed.
- ASSERT(state_ == PREPARE_GC);
+ ASSERT(data.state_ == MarkCompactCollectorData::PREPARE_GC);
// Prepare has selected whether to compact the old generation or not.
// Tell the tracer.
- if (IsCompacting()) tracer_->set_is_compacting();
+ if (IsCompacting()) data.tracer_->set_is_compacting();
MarkLiveObjects();
@@ -94,32 +71,33 @@
// Save the count of marked objects remaining after the collection and
// null out the GC tracer.
- previous_marked_count_ = tracer_->marked_count();
- ASSERT(previous_marked_count_ == 0);
- tracer_ = NULL;
+ data.previous_marked_count_ = data.tracer_->marked_count();
+ ASSERT(data.previous_marked_count_ == 0);
+ data.tracer_ = NULL;
}
void MarkCompactCollector::Prepare(GCTracer* tracer) {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
// Rather than passing the tracer around we stash it in a static member
// variable.
- tracer_ = tracer;
+ data.tracer_ = tracer;
#ifdef DEBUG
- ASSERT(state_ == IDLE);
- state_ = PREPARE_GC;
+ ASSERT(data.state_ == MarkCompactCollectorData::IDLE);
+ data.state_ = MarkCompactCollectorData::PREPARE_GC;
#endif
ASSERT(!FLAG_always_compact || !FLAG_never_compact);
- compacting_collection_ =
- FLAG_always_compact || force_compaction_ || compact_on_next_gc_;
- compact_on_next_gc_ = false;
+ data.compacting_collection_ =
+ FLAG_always_compact || data.force_compaction_ || data.compact_on_next_gc_;
+ data.compact_on_next_gc_ = false;
- if (FLAG_never_compact) compacting_collection_ = false;
+ if (FLAG_never_compact) data.compacting_collection_ = false;
if (FLAG_collect_maps) CreateBackPointers();
#ifdef DEBUG
- if (compacting_collection_) {
+ if (data.compacting_collection_) {
// We will write bookkeeping information to the remembered set area
// starting now.
Page::set_rset_state(Page::NOT_IN_USE);
@@ -128,26 +106,28 @@
PagedSpaces spaces;
while (PagedSpace* space = spaces.next()) {
- space->PrepareForMarkCompact(compacting_collection_);
+ space->PrepareForMarkCompact(data.compacting_collection_);
}
#ifdef DEBUG
- live_bytes_ = 0;
- live_young_objects_ = 0;
- live_old_pointer_objects_ = 0;
- live_old_data_objects_ = 0;
- live_code_objects_ = 0;
- live_map_objects_ = 0;
- live_cell_objects_ = 0;
- live_lo_objects_ = 0;
+ data.live_bytes_ = 0;
+ data.live_young_objects_ = 0;
+ data.live_old_pointer_objects_ = 0;
+ data.live_old_data_objects_ = 0;
+ data.live_code_objects_ = 0;
+ data.live_map_objects_ = 0;
+ data.live_cell_objects_ = 0;
+ data.live_lo_objects_ = 0;
#endif
}
void MarkCompactCollector::Finish() {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
#ifdef DEBUG
- ASSERT(state_ == SWEEP_SPACES || state_ == REBUILD_RSETS);
- state_ = IDLE;
+ ASSERT(data.state_ == MarkCompactCollectorData::SWEEP_SPACES ||
+ data.state_ == MarkCompactCollectorData::REBUILD_RSETS);
+ data.state_ = MarkCompactCollectorData::IDLE;
#endif
// The stub cache is not traversed during GC; clear the cache to
// force lazy re-initialization of it. This must be done after the
@@ -177,11 +157,12 @@
static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
if (old_gen_fragmentation > kFragmentationLimit &&
old_gen_recoverable > kFragmentationAllowed) {
- compact_on_next_gc_ = true;
+ data.compact_on_next_gc_ = true;
}
}
-
+class MarkCompactCollectorPrivateData {
+ public:
// -------------------------------------------------------------------------
// Phase 1: tracing and marking live objects.
// before: all objects are in normal state.
@@ -210,9 +191,38 @@
// and continue with marking. This process repeats until all reachable
// objects have been marked.
-static MarkingStack marking_stack;
+ MarkingStack marking_stack_;
+ MarkCompactCollectorPrivateData() {}
+ DISALLOW_COPY_AND_ASSIGN(MarkCompactCollectorPrivateData);
+};
+MarkCompactCollectorData::MarkCompactCollectorData()
+ :force_compaction_(false),
+ compacting_collection_(false),
+ compact_on_next_gc_(false),
+ previous_marked_count_(0),
+#ifdef DEBUG
+ state_(IDLE),
+// Counters used for debugging the marking phase of mark-compact or mark-sweep
+// collection.
+ live_bytes_(0),
+ live_young_objects_(0),
+ live_old_data_objects_(0),
+ live_old_pointer_objects_(0),
+ live_code_objects_(0),
+ live_map_objects_(0),
+ live_cell_objects_(0),
+ live_lo_objects_(0),
+#endif
+ tracer_(NULL),
+ private_data_(*new MarkCompactCollectorPrivateData()) {
+}
+
+MarkCompactCollectorData::~MarkCompactCollectorData() {
+ delete &private_data_;
+}
+
static inline HeapObject* ShortCircuitConsString(Object** p) {
// Optimization: If the heap object pointed to by p is a non-symbol
// cons string whose right substring is Heap::empty_string, update
@@ -423,6 +433,9 @@
void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) {
ASSERT(!object->IsMarked());
ASSERT(Heap::Contains(object));
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
+
if (object->IsMap()) {
Map* map = Map::cast(object);
if (FLAG_cleanup_caches_in_maps_at_gc) {
@@ -470,6 +483,8 @@
ASSERT(contents->IsFixedArray());
ASSERT(contents->length() >= 2);
SetMark(contents);
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
// Contents contains (value, details) pairs. If the details say
// that the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION,
// or NULL_DESCRIPTOR, we don't mark the value as live. Only for
@@ -524,6 +539,8 @@
// is reached, whichever comes first.
template<class T>
static void ScanOverflowedObjects(T* it) {
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
// The caller should ensure that the marking stack is initially not full,
// so that we don't waste effort pointlessly scanning for objects.
ASSERT(!marking_stack.is_full());
@@ -597,6 +614,8 @@
// Handle the symbol table specially.
MarkSymbolTable();
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
// There may be overflowed objects in the heap. Visit them now.
while (marking_stack.overflowed()) {
RefillMarkingStack();
@@ -644,6 +663,8 @@
// After: the marking stack is empty, and all objects reachable from the
// marking stack have been marked, or are overflowed in the heap.
void MarkCompactCollector::EmptyMarkingStack(MarkingVisitor* visitor) {
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
while (!marking_stack.is_empty()) {
HeapObject* object = marking_stack.Pop();
ASSERT(object->IsHeapObject());
@@ -669,6 +690,8 @@
// overflowed objects in the heap so the overflow flag on the markings stack
// is cleared.
void MarkCompactCollector::RefillMarkingStack() {
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
ASSERT(marking_stack.overflowed());
SemiSpaceIterator new_it(Heap::new_space(), &OverflowObjectSize);
@@ -709,6 +732,8 @@
// pointers. After: the marking stack is empty and there are no overflowed
// objects in the heap.
void MarkCompactCollector::ProcessMarkingStack(MarkingVisitor* visitor) {
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
EmptyMarkingStack(visitor);
while (marking_stack.overflowed()) {
RefillMarkingStack();
@@ -718,6 +743,8 @@
void MarkCompactCollector::ProcessObjectGroups(MarkingVisitor* visitor) {
+ MarkingStack& marking_stack = v8_context()->mark_compact_collector_data_.
+ private_data_.marking_stack_;
bool work_to_do = true;
ASSERT(marking_stack.is_empty());
while (work_to_do) {
@@ -729,10 +756,12 @@
void MarkCompactCollector::MarkLiveObjects() {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
#ifdef DEBUG
- ASSERT(state_ == PREPARE_GC);
- state_ = MARK_LIVE_OBJECTS;
+ ASSERT(data.state_ == MarkCompactCollectorData::PREPARE_GC);
+ data.state_ = MarkCompactCollectorData::MARK_LIVE_OBJECTS;
#endif
+ MarkingStack& marking_stack = data.private_data_.marking_stack_;
// The to space contains live objects, the from space is used as a marking
// stack.
marking_stack.Initialize(Heap::new_space()->FromSpaceLow(),
@@ -789,23 +818,24 @@
#ifdef DEBUG
void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
- live_bytes_ += obj->Size();
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
+ data.live_bytes_ += obj->Size();
if (Heap::new_space()->Contains(obj)) {
- live_young_objects_++;
+ data.live_young_objects_++;
} else if (Heap::map_space()->Contains(obj)) {
ASSERT(obj->IsMap());
- live_map_objects_++;
+ data.live_map_objects_++;
} else if (Heap::cell_space()->Contains(obj)) {
ASSERT(obj->IsJSGlobalPropertyCell());
- live_cell_objects_++;
+ data.live_cell_objects_++;
} else if (Heap::old_pointer_space()->Contains(obj)) {
- live_old_pointer_objects_++;
+ data.live_old_pointer_objects_++;
} else if (Heap::old_data_space()->Contains(obj)) {
- live_old_data_objects_++;
+ data.live_old_data_objects_++;
} else if (Heap::code_space()->Contains(obj)) {
- live_code_objects_++;
+ data.live_code_objects_++;
} else if (Heap::lo_space()->Contains(obj)) {
- live_lo_objects_++;
+ data.live_lo_objects_++;
} else {
UNREACHABLE();
}
@@ -815,9 +845,11 @@
void MarkCompactCollector::SweepLargeObjectSpace() {
#ifdef DEBUG
- ASSERT(state_ == MARK_LIVE_OBJECTS);
- state_ =
- compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES;
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
+ ASSERT(data.state_ == MarkCompactCollectorData::MARK_LIVE_OBJECTS);
+ data.state_ = data.compacting_collection_ ?
+ MarkCompactCollectorData::ENCODE_FORWARDING_ADDRESSES :
+ MarkCompactCollectorData::SWEEP_SPACES;
#endif
// Deallocate unmarked objects and clear marked bits for marked objects.
Heap::lo_space()->FreeUnmarkedObjects();
@@ -1248,7 +1280,8 @@
void MarkCompactCollector::EncodeForwardingAddresses() {
- ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
+ ASSERT(v8_context()->mark_compact_collector_data_.state_ ==
+ MarkCompactCollectorData::ENCODE_FORWARDING_ADDRESSES);
// Objects in the active semispace of the young generation may be
// relocated to the inactive semispace (if not promoted). Set the
// relocation info to the beginning of the inactive semispace.
@@ -1295,7 +1328,8 @@
void MarkCompactCollector::SweepSpaces() {
- ASSERT(state_ == SWEEP_SPACES);
+ ASSERT(v8_context()->mark_compact_collector_data_.state_ ==
+ MarkCompactCollectorData::SWEEP_SPACES);
ASSERT(!IsCompacting());
// Noncompacting collections simply sweep the spaces to clear the mark
// bits and free the nonlive blocks (for old and map spaces). We sweep
@@ -1339,14 +1373,22 @@
int MarkCompactCollector::IterateLiveObjects(NewSpace* space,
HeapObjectCallback size_f) {
- ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
+#ifdef DEBUG
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
+ ASSERT(MarkCompactCollectorData::MARK_LIVE_OBJECTS < data.state_ &&
+ data.state_ <= MarkCompactCollectorData::RELOCATE_OBJECTS);
+#endif
return IterateLiveObjectsInRange(space->bottom(), space->top(), size_f);
}
int MarkCompactCollector::IterateLiveObjects(PagedSpace* space,
HeapObjectCallback size_f) {
- ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
+#ifdef DEBUG
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
+ ASSERT(MarkCompactCollectorData::MARK_LIVE_OBJECTS < data.state_ &&
+ data.state_ <= MarkCompactCollectorData::RELOCATE_OBJECTS);
+#endif
int total = 0;
PageIterator it(space, PageIterator::PAGES_IN_USE);
while (it.has_next()) {
@@ -1451,9 +1493,10 @@
void MarkCompactCollector::UpdatePointers() {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
#ifdef DEBUG
- ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
- state_ = UPDATE_POINTERS;
+ ASSERT(data.state_ == MarkCompactCollectorData::ENCODE_FORWARDING_ADDRESSES);
+ data.state_ = MarkCompactCollectorData::UPDATE_POINTERS;
#endif
UpdatingVisitor updating_visitor;
Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
@@ -1482,12 +1525,12 @@
USE(live_codes);
USE(live_cells);
USE(live_news);
- ASSERT(live_maps == live_map_objects_);
- ASSERT(live_data_olds == live_old_data_objects_);
- ASSERT(live_pointer_olds == live_old_pointer_objects_);
- ASSERT(live_codes == live_code_objects_);
- ASSERT(live_cells == live_cell_objects_);
- ASSERT(live_news == live_young_objects_);
+ ASSERT(live_maps == data.live_map_objects_);
+ ASSERT(live_data_olds == data.live_old_data_objects_);
+ ASSERT(live_pointer_olds == data.live_old_pointer_objects_);
+ ASSERT(live_codes == data.live_code_objects_);
+ ASSERT(live_cells == data.live_cell_objects_);
+ ASSERT(live_news == data.live_young_objects_);
}
@@ -1596,9 +1639,10 @@
// Phase 4: Relocate objects
void MarkCompactCollector::RelocateObjects() {
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
#ifdef DEBUG
- ASSERT(state_ == UPDATE_POINTERS);
- state_ = RELOCATE_OBJECTS;
+ ASSERT(data.state_ == MarkCompactCollectorData::UPDATE_POINTERS);
+ data.state_ = MarkCompactCollectorData::RELOCATE_OBJECTS;
#endif
// Relocates objects, always relocate map objects first. Relocating
// objects in other space relies on map objects to get object size.
@@ -1617,12 +1661,12 @@
USE(live_codes);
USE(live_cells);
USE(live_news);
- ASSERT(live_maps == live_map_objects_);
- ASSERT(live_data_olds == live_old_data_objects_);
- ASSERT(live_pointer_olds == live_old_pointer_objects_);
- ASSERT(live_codes == live_code_objects_);
- ASSERT(live_cells == live_cell_objects_);
- ASSERT(live_news == live_young_objects_);
+ ASSERT(live_maps == data.live_map_objects_);
+ ASSERT(live_data_olds == data.live_old_data_objects_);
+ ASSERT(live_pointer_olds == data.live_old_pointer_objects_);
+ ASSERT(live_codes == data.live_code_objects_);
+ ASSERT(live_cells == data.live_cell_objects_);
+ ASSERT(live_news == data.live_young_objects_);
// Flip from and to spaces
Heap::new_space()->Flip();
@@ -1808,8 +1852,9 @@
void MarkCompactCollector::RebuildRSets() {
#ifdef DEBUG
- ASSERT(state_ == RELOCATE_OBJECTS);
- state_ = REBUILD_RSETS;
+ MarkCompactCollectorData& data = v8_context()->mark_compact_collector_data_;
+ ASSERT(data.state_ == MarkCompactCollectorData::RELOCATE_OBJECTS);
+ data.state_ = MarkCompactCollectorData::REBUILD_RSETS;
#endif
Heap::RebuildRSets();
}
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698