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

Unified Diff: src/heap.cc

Issue 115086: Change the scavenging collector so that promoted objects do not reside... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 7 months 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 | « no previous file | src/heap-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
===================================================================
--- src/heap.cc (revision 1953)
+++ src/heap.cc (working copy)
@@ -537,8 +537,39 @@
};
+// A queue of pointers and maps of to-be-promoted objects during a
+// scavenge collection.
+class PromotionQueue {
+ public:
+ void Initialize(Address start_address) {
+ front_ = rear_ = reinterpret_cast<HeapObject**>(start_address);
+ }
+
+ bool is_empty() { return front_ <= rear_; }
+
+ void insert(HeapObject* object, Map* map) {
+ *(--rear_) = object;
+ *(--rear_) = map;
+ // Assert no overflow into live objects.
+ ASSERT(rear_ >= Heap::new_space()->top());
+ }
+
+ void remove(HeapObject** object, Map** map) {
+ *object = *(--front_);
+ *map = Map::cast(*(--front_));
+ // Assert no underflow.
+ ASSERT(front_ >= rear_);
+ }
+
+ private:
+ // The front of the queue is higher in memory than the rear.
+ HeapObject** front_;
+ HeapObject** rear_;
+};
+
+
// Shared state read by the scavenge collector and set by ScavengeObject.
-static Address promoted_rear = NULL;
+static PromotionQueue promotion_queue;
#ifdef DEBUG
@@ -624,8 +655,7 @@
// frees up its size in bytes from the top of the new space, and
// objects are at least one pointer in size.
Address new_space_front = new_space_.ToSpaceLow();
- Address promoted_front = new_space_.ToSpaceHigh();
- promoted_rear = new_space_.ToSpaceHigh();
+ promotion_queue.Initialize(new_space_.ToSpaceHigh());
ScavengeVisitor scavenge_visitor;
// Copy roots.
@@ -642,7 +672,6 @@
do {
ASSERT(new_space_front <= new_space_.top());
- ASSERT(promoted_front >= promoted_rear);
// The addresses new_space_front and new_space_.top() define a
// queue of unprocessed copied objects. Process them until the
@@ -653,15 +682,26 @@
new_space_front += object->Size();
}
- // The addresses promoted_front and promoted_rear define a queue
- // of unprocessed addresses of promoted objects. Process them
- // until the queue is empty.
- while (promoted_front > promoted_rear) {
- promoted_front -= kPointerSize;
- HeapObject* object =
- HeapObject::cast(Memory::Object_at(promoted_front));
- object->Iterate(&scavenge_visitor);
- UpdateRSet(object);
+ // Promote and process all the to-be-promoted objects.
+ while (!promotion_queue.is_empty()) {
+ HeapObject* source;
+ Map* map;
+ promotion_queue.remove(&source, &map);
+ // Copy the from-space object to its new location (given by the
+ // forwarding address) and fix its map.
+ HeapObject* target = source->map_word().ToForwardingAddress();
+ CopyBlock(reinterpret_cast<Object**>(target->address()),
+ reinterpret_cast<Object**>(source->address()),
+ source->SizeFromMap(map));
+ target->set_map(map);
+
+#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
+ // Update NewSpace stats if necessary.
+ RecordCopiedObject(target);
+#endif
+ // Visit the newly copied object for pointers to new space.
+ target->Iterate(&scavenge_visitor);
+ UpdateRSet(target);
}
// Take another spin if there are now unswept objects in new space
@@ -818,8 +858,8 @@
// Set the forwarding address.
source->set_map_word(MapWord::FromForwardingAddress(target));
+#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
// Update NewSpace stats if necessary.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
RecordCopiedObject(target);
#endif
@@ -827,28 +867,6 @@
}
-// Inlined function.
-void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
- ASSERT(InFromSpace(object));
-
- // We use the first word (where the map pointer usually is) of a heap
- // object to record the forwarding pointer. A forwarding pointer can
- // point to an old space, the code space, or the to space of the new
- // generation.
- MapWord first_word = object->map_word();
-
- // If the first word is a forwarding address, the object has already been
- // copied.
- if (first_word.IsForwardingAddress()) {
- *p = first_word.ToForwardingAddress();
- return;
- }
-
- // Call the slow part of scavenge object.
- return ScavengeObjectSlow(p, object);
-}
-
-
static inline bool IsShortcutCandidate(HeapObject* object, Map* map) {
STATIC_ASSERT(kNotStringTag != 0 && kSymbolTag != 0);
ASSERT(object->map() == map);
@@ -879,6 +897,11 @@
}
int object_size = object->SizeFromMap(first_word.ToMap());
+ // We rely on live objects in new space to be at least two pointers,
+ // so we can store the from-space address and map pointer of promoted
+ // objects in the to space.
+ ASSERT(object_size >= 2 * kPointerSize);
+
// If the object should be promoted, we try to copy it to old space.
if (ShouldBePromoted(object->address(), object_size)) {
OldSpace* target_space = Heap::TargetSpace(object);
@@ -886,16 +909,29 @@
target_space == Heap::old_data_space_);
Object* result = target_space->AllocateRaw(object_size);
if (!result->IsFailure()) {
- *p = MigrateObject(object, HeapObject::cast(result), object_size);
+ HeapObject* target = HeapObject::cast(result);
if (target_space == Heap::old_pointer_space_) {
- // Record the object's address at the top of the to space, to allow
- // it to be swept by the scavenger.
- promoted_rear -= kPointerSize;
- Memory::Object_at(promoted_rear) = *p;
+ // Save the from-space object pointer and its map pointer at the
+ // top of the to space to be swept and copied later. Write the
+ // forwarding address over the map word of the from-space
+ // object.
+ promotion_queue.insert(object, first_word.ToMap());
+ object->set_map_word(MapWord::FromForwardingAddress(target));
+
+ // Give the space allocated for the result a proper map by
+ // treating it as a free list node (not linked into the free
+ // list).
+ FreeListNode* node = FreeListNode::FromAddress(target->address());
+ node->set_size(object_size);
+
+ *p = target;
} else {
+ // Objects promoted to the data space can be copied immediately
+ // and not revisited---we will never sweep that space for
+ // pointers and the copied objects do not contain pointers to
+ // new space objects.
+ *p = MigrateObject(object, target, object_size);
#ifdef DEBUG
- // Objects promoted to the data space should not have pointers to
- // new space.
VerifyNonPointerSpacePointersVisitor v;
(*p)->Iterate(&v);
#endif
« no previous file with comments | « no previous file | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698