Revision: 9194
Author: [email protected]
Date: Thu Sep 8 05:15:24 2011
Log: Fix several bugs in compaction:
- when evicting evacuation candidates from free list create filler covering
[top, limit) to ensure that page will remain iterable if it was iterable.
this is important for Code space pages.
- we should not split typed slots between two slots buffers because we
traverse them in opposite order.
- when recording reloc slot ensure that reloc host is not null before
checking host's page flags.
[email protected]
BUG=
TEST=
Review URL: http://codereview.chromium.org/7841036
http://code.google.com/p/v8/source/detail?r=9194
Modified:
/branches/experimental/gc/src/flag-definitions.h
/branches/experimental/gc/src/mark-compact.cc
/branches/experimental/gc/src/mark-compact.h
/branches/experimental/gc/src/objects-visiting-inl.h
/branches/experimental/gc/src/spaces.cc
=======================================
--- /branches/experimental/gc/src/flag-definitions.h Mon Aug 29 05:23:10
2011
+++ /branches/experimental/gc/src/flag-definitions.h Thu Sep 8 05:15:24
2011
@@ -252,6 +252,8 @@
"print cumulative GC statistics in name=value format on exit")
DEFINE_bool(trace_gc_verbose, false,
"print more details following each garbage collection")
+DEFINE_bool(trace_fragmentation, false,
+ "report fragmentation for old pointer and data pages")
DEFINE_bool(collect_maps, true,
"garbage collect maps from which no objects can be reached")
DEFINE_bool(flush_code, false,
@@ -457,8 +459,6 @@
DEFINE_bool(collect_heap_spill_statistics, false,
"report heap spill statistics along with heap_stats "
"(requires heap_stats)")
-DEFINE_bool(trace_fragmentation, false,
- "report fragmentation for old pointer and data pages")
DEFINE_bool(trace_isolates, false, "trace isolate state changes")
=======================================
--- /branches/experimental/gc/src/mark-compact.cc Thu Sep 8 05:04:27 2011
+++ /branches/experimental/gc/src/mark-compact.cc Thu Sep 8 05:15:24 2011
@@ -426,7 +426,6 @@
void MarkCompactCollector::Prepare(GCTracer* tracer) {
FLAG_flush_code = false;
- FLAG_always_compact = false;
// Disable collection of maps if incremental marking is enabled.
// Map collection algorithm relies on a special map transition tree
traversal
@@ -3418,16 +3417,19 @@
SlotType type,
Address addr,
AdditionMode mode) {
- if (!AddTo(allocator,
- buffer_address,
- reinterpret_cast<ObjectSlot>(type),
- mode)) {
- return false;
- }
- return AddTo(allocator,
- buffer_address,
- reinterpret_cast<ObjectSlot>(addr),
- mode);
+ SlotsBuffer* buffer = *buffer_address;
+ if (buffer == NULL || !buffer->HasSpaceForTypedSlot()) {
+ if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) {
+ allocator->DeallocateChain(buffer_address);
+ return false;
+ }
+ buffer = allocator->AllocateBuffer(buffer);
+ *buffer_address = buffer;
+ }
+ ASSERT(buffer->HasSpaceForTypedSlot());
+ buffer->Add(reinterpret_cast<ObjectSlot>(type));
+ buffer->Add(reinterpret_cast<ObjectSlot>(addr));
+ return true;
}
@@ -3440,7 +3442,7 @@
return SlotsBuffer::JS_RETURN_SLOT;
}
UNREACHABLE();
- return SlotsBuffer::NONE;
+ return SlotsBuffer::NUMBER_OF_SLOT_TYPES;
}
@@ -3448,7 +3450,8 @@
Page* target_page = Page::FromAddress(
reinterpret_cast<Address>(target));
if (target_page->IsEvacuationCandidate() &&
- !ShouldSkipEvacuationSlotRecording(rinfo->host())) {
+ (rinfo->host() == NULL ||
+ !ShouldSkipEvacuationSlotRecording(rinfo->host()))) {
if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
target_page->slots_buffer_address(),
SlotTypeForRMode(rinfo->rmode()),
@@ -3482,32 +3485,21 @@
}
-SlotsBuffer::SlotType SlotsBuffer::UpdateSlots(
- Heap* heap,
- SlotsBuffer::SlotType pending) {
+void SlotsBuffer::UpdateSlots(Heap* heap) {
PointersUpdatingVisitor v(heap);
- if (pending != NONE) {
- UpdateSlot(&v, pending, reinterpret_cast<Address>(slots_[0]));
- }
-
for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) {
ObjectSlot slot = slots_[slot_idx];
if (!IsTypedSlot(slot)) {
UpdateSlot(slot);
} else {
++slot_idx;
- if (slot_idx < idx_) {
- UpdateSlot(&v,
- DecodeSlotType(slot),
- reinterpret_cast<Address>(slots_[slot_idx]));
- } else {
- return DecodeSlotType(slot);
- }
+ ASSERT(slot_idx < idx_);
+ UpdateSlot(&v,
+ DecodeSlotType(slot),
+ reinterpret_cast<Address>(slots_[slot_idx]));
}
}
-
- return SlotsBuffer::NONE;
}
=======================================
--- /branches/experimental/gc/src/mark-compact.h Tue Sep 6 08:11:38 2011
+++ /branches/experimental/gc/src/mark-compact.h Thu Sep 8 05:15:24 2011
@@ -308,7 +308,6 @@
}
enum SlotType {
- NONE,
RELOCATED_CODE_OBJECT,
CODE_TARGET_SLOT,
CODE_ENTRY_SLOT,
@@ -317,16 +316,7 @@
NUMBER_OF_SLOT_TYPES
};
- // Typed slot might be splitted between two SlotsBuffers: slot's type
- // is recorded in one buffer and type address is recorded as the first
- // slot in the next buffer.
- //
- // If the first address recorded in this buffer is address of the typed
- // slot then it's type will be passed as pending argument.
- //
- // If this buffer ends on slot's type and the next buffer is expected to
- // contain address of a typed slot then the function returns that type.
- SlotType UpdateSlots(Heap* heap, SlotType pending);
+ void UpdateSlots(Heap* heap);
SlotsBuffer* next() { return next_; }
@@ -339,11 +329,14 @@
inline bool IsFull() {
return idx_ == kNumberOfElements;
}
+
+ inline bool HasSpaceForTypedSlot() {
+ return idx_ < kNumberOfElements - 1;
+ }
static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer) {
- SlotType pending = NONE;
while (buffer != NULL) {
- pending = buffer->UpdateSlots(heap, pending);
+ buffer->UpdateSlots(heap);
buffer = buffer->next();
}
}
@@ -353,15 +346,17 @@
IGNORE_OVERFLOW
};
+ static bool ChainLengthThresholdReached(SlotsBuffer* buffer) {
+ return buffer != NULL && buffer->chain_length_ >=
kChainLengthThreshold;
+ }
+
static bool AddTo(SlotsBufferAllocator* allocator,
SlotsBuffer** buffer_address,
ObjectSlot slot,
AdditionMode mode) {
SlotsBuffer* buffer = *buffer_address;
if (buffer == NULL || buffer->IsFull()) {
- if (mode == FAIL_ON_OVERFLOW &&
- buffer != NULL &&
- buffer->chain_length_ >= kChainLengthThreshold) {
+ if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer))
{
allocator->DeallocateChain(buffer_address);
return false;
}
=======================================
--- /branches/experimental/gc/src/objects-visiting-inl.h Wed Aug 10
05:50:30 2011
+++ /branches/experimental/gc/src/objects-visiting-inl.h Thu Sep 8
05:15:24 2011
@@ -99,13 +99,10 @@
RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
- // Use the relocation info pointer before it is visited by
- // the heap compaction in the next statement.
- RelocIterator it(this, mode_mask);
-
IteratePointer(v, kRelocationInfoOffset);
IteratePointer(v, kDeoptimizationDataOffset);
+ RelocIterator it(this, mode_mask);
for (; !it.done(); it.next()) {
it.rinfo()->Visit(v);
}
@@ -122,10 +119,6 @@
RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
- // Use the relocation info pointer before it is visited by
- // the heap compaction in the next statement.
- RelocIterator it(this, mode_mask);
-
StaticVisitor::VisitPointer(
heap,
reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset));
@@ -133,6 +126,7 @@
heap,
reinterpret_cast<Object**>(this->address() +
kDeoptimizationDataOffset));
+ RelocIterator it(this, mode_mask);
for (; !it.done(); it.next()) {
it.rinfo()->template Visit<StaticVisitor>(heap);
}
=======================================
--- /branches/experimental/gc/src/spaces.cc Thu Aug 25 03:42:12 2011
+++ /branches/experimental/gc/src/spaces.cc Thu Sep 8 05:15:24 2011
@@ -2020,8 +2020,13 @@
if (allocation_info_.top >= allocation_info_.limit) return;
if (Page::FromAddress(allocation_info_.top)->IsEvacuationCandidate()) {
- allocation_info_.top = NULL;
- allocation_info_.limit = NULL;
+ // Create filler object to keep page iterable if it was iterable.
+ int remaining =
+ static_cast<int>(allocation_info_.limit - allocation_info_.top);
+ heap()->CreateFillerObjectAt(allocation_info_.top, remaining);
+
+ allocation_info_.top = NULL;
+ allocation_info_.limit = NULL;
}
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev