Commit 43f33038 authored by hpayer's avatar hpayer Committed by Commit bot

Record slots in large objects.

BUG=

Review URL: https://codereview.chromium.org/1296713007

Cr-Commit-Position: refs/heads/master@{#30299}
parent 9271b0cc
......@@ -429,8 +429,6 @@ void GCTracer::PrintNVP() const {
PrintF("sweepcode=%.2f ", current_.scopes[Scope::MC_SWEEP_CODE]);
PrintF("sweepcell=%.2f ", current_.scopes[Scope::MC_SWEEP_CELL]);
PrintF("sweepmap=%.2f ", current_.scopes[Scope::MC_SWEEP_MAP]);
PrintF("rescan_lo=%.2f ",
current_.scopes[Scope::MC_RESCAN_LARGE_OBJECTS]);
PrintF("evacuate=%.1f ", current_.scopes[Scope::MC_EVACUATE_PAGES]);
PrintF("new_new=%.1f ",
current_.scopes[Scope::MC_UPDATE_NEW_TO_NEW_POINTERS]);
......
......@@ -105,7 +105,6 @@ class GCTracer {
MC_SWEEP_CODE,
MC_SWEEP_CELL,
MC_SWEEP_MAP,
MC_RESCAN_LARGE_OBJECTS,
MC_EVACUATE_PAGES,
MC_UPDATE_NEW_TO_NEW_POINTERS,
MC_UPDATE_ROOT_TO_NEW_POINTERS,
......
......@@ -298,12 +298,6 @@ void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
if (is_marking) {
chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
// It's difficult to filter out slots recorded for large objects.
if (chunk->owner()->identity() == LO_SPACE &&
chunk->size() > static_cast<size_t>(Page::kPageSize) && is_compacting) {
chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
}
} else {
chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
......
......@@ -3634,24 +3634,6 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
PrintF(" migration slots buffer: %d\n",
SlotsBuffer::SizeOfChain(migration_slots_buffer_));
}
if (compacting_ && was_marked_incrementally_) {
GCTracer::Scope gc_scope(heap()->tracer(),
GCTracer::Scope::MC_RESCAN_LARGE_OBJECTS);
// It's difficult to filter out slots recorded for large objects.
LargeObjectIterator it(heap_->lo_space());
for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
// LargeObjectSpace is not swept yet thus we have to skip
// dead objects explicitly.
if (!IsMarked(obj)) continue;
Page* p = Page::FromAddress(obj->address());
if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
obj->Iterate(&updating_visitor);
p->ClearFlag(Page::RESCAN_ON_EVACUATION);
}
}
}
}
int npages = evacuation_candidates_.length();
......
......@@ -556,7 +556,8 @@ static inline void SimulateFullSpace(v8::internal::PagedSpace* space) {
// Helper function that simulates many incremental marking steps until
// marking is completed.
static inline void SimulateIncrementalMarking(i::Heap* heap) {
static inline void SimulateIncrementalMarking(i::Heap* heap,
bool force_completion = true) {
i::MarkCompactCollector* collector = heap->mark_compact_collector();
i::IncrementalMarking* marking = heap->incremental_marking();
if (collector->sweeping_in_progress()) {
......@@ -567,6 +568,8 @@ static inline void SimulateIncrementalMarking(i::Heap* heap) {
marking->Start(i::Heap::kNoGCFlags);
}
CHECK(marking->IsMarking());
if (!force_completion) return;
while (!marking->IsComplete()) {
marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
if (marking->IsReadyToOverApproximateWeakClosure()) {
......
......@@ -4701,6 +4701,49 @@ TEST(Regress514122) {
}
TEST(LargeObjectSlotRecording) {
FLAG_manual_evacuation_candidates_selection = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
// Create an object on an evacuation candidate.
SimulateFullSpace(heap->old_space());
Handle<FixedArray> lit = isolate->factory()->NewFixedArray(4, TENURED);
Page* evac_page = Page::FromAddress(lit->address());
evac_page->SetFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING);
FixedArray* old_location = *lit;
// Allocate a large object.
const int kSize = 1000000;
Handle<FixedArray> lo = isolate->factory()->NewFixedArray(kSize, TENURED);
CHECK(heap->lo_space()->Contains(*lo));
// Start incremental marking to active write barrier.
SimulateIncrementalMarking(heap, false);
heap->AdvanceIncrementalMarking(10000000, 10000000,
IncrementalMarking::IdleStepActions());
// Create references from the large object to the object on the evacuation
// candidate.
const int kStep = kSize / 10;
for (int i = 0; i < kSize; i += kStep) {
lo->set(i, *lit);
CHECK(lo->get(i) == old_location);
}
// Move the evaucation candidate object.
CcTest::heap()->CollectAllGarbage();
// Verify that the pointers in the large object got updated.
for (int i = 0; i < kSize; i += kStep) {
CHECK_EQ(lo->get(i), *lit);
CHECK(lo->get(i) != old_location);
}
}
class DummyVisitor : public ObjectVisitor {
public:
void VisitPointers(Object** start, Object** end) { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment