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

Side by Side Diff: src/heap/mark-compact.cc

Issue 1295713004: Untangle slots buffer part 1: Make invalid slots filtering part of MarkCompactCollector. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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 unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/mark-compact.h" 5 #include "src/heap/mark-compact.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 return compacting_; 283 return compacting_;
284 } 284 }
285 285
286 286
287 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { 287 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() {
288 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); 288 heap_->store_buffer()->ClearInvalidStoreBufferEntries();
289 289
290 int number_of_pages = evacuation_candidates_.length(); 290 int number_of_pages = evacuation_candidates_.length();
291 for (int i = 0; i < number_of_pages; i++) { 291 for (int i = 0; i < number_of_pages; i++) {
292 Page* p = evacuation_candidates_[i]; 292 Page* p = evacuation_candidates_[i];
293 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); 293 ClearInvalidSlotsBufferEntries(p->slots_buffer());
294 }
295 }
296
297
298 void MarkCompactCollector::ClearInvalidSlotsBufferEntries(SlotsBuffer* buffer) {
299 // Remove entries by replacing them with an old-space slot containing a smi
300 // that is located in an unmovable page.
301 const SlotsBuffer::ObjectSlot kRemovedEntry = HeapObject::RawField(
302 heap_->empty_fixed_array(), FixedArrayBase::kLengthOffset);
303 DCHECK(Page::FromAddress(reinterpret_cast<Address>(kRemovedEntry))
304 ->NeverEvacuate());
305
306 while (buffer != NULL) {
307 for (int slot_idx = 0; slot_idx < buffer->Size(); ++slot_idx) {
308 SlotsBuffer::ObjectSlot slot = buffer->Get(slot_idx);
309 if (!SlotsBuffer::IsTypedSlot(slot)) {
310 Object* object = *slot;
311 if ((object->IsHeapObject() && heap_->InNewSpace(object)) ||
312 !heap_->mark_compact_collector()->IsSlotInLiveObject(
313 reinterpret_cast<Address>(slot))) {
314 buffer->Set(slot_idx, kRemovedEntry);
315 }
316 } else {
317 ++slot_idx;
318 DCHECK(slot_idx < buffer->Size());
319 }
320 }
321 buffer = buffer->next();
294 } 322 }
295 } 323 }
296 324
297 325
298 #ifdef VERIFY_HEAP 326 #ifdef VERIFY_HEAP
327 void VerifySlots(Heap* heap, SlotsBuffer* buffer) {
328 while (buffer != NULL) {
329 for (int slot_idx = 0; slot_idx < buffer->Size(); ++slot_idx) {
330 SlotsBuffer::ObjectSlot slot = buffer->Get(slot_idx);
331 if (!SlotsBuffer::IsTypedSlot(slot)) {
332 Object* object = *slot;
333 if (object->IsHeapObject()) {
334 HeapObject* heap_object = HeapObject::cast(object);
335 CHECK(!heap->InNewSpace(object));
336 heap->mark_compact_collector()->VerifyIsSlotInLiveObject(
337 reinterpret_cast<Address>(slot), heap_object);
338 }
339 } else {
340 ++slot_idx;
341 DCHECK(slot_idx < buffer->Size());
342 }
343 }
344 buffer = buffer->next();
345 }
346 }
347
348
299 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { 349 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) {
300 PageIterator it(space); 350 PageIterator it(space);
301 while (it.has_next()) { 351 while (it.has_next()) {
302 Page* p = it.next(); 352 Page* p = it.next();
303 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); 353 VerifySlots(heap, p->slots_buffer());
304 } 354 }
305 } 355 }
306 356
307 357
308 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) { 358 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) {
309 heap->store_buffer()->VerifyValidStoreBufferEntries(); 359 heap->store_buffer()->VerifyValidStoreBufferEntries();
310 360
311 VerifyValidSlotsBufferEntries(heap, heap->old_space()); 361 VerifyValidSlotsBufferEntries(heap, heap->old_space());
312 VerifyValidSlotsBufferEntries(heap, heap->code_space()); 362 VerifyValidSlotsBufferEntries(heap, heap->code_space());
313 VerifyValidSlotsBufferEntries(heap, heap->map_space()); 363 VerifyValidSlotsBufferEntries(heap, heap->map_space());
314
315 LargeObjectIterator it(heap->lo_space());
Michael Lippautz 2015/08/18 09:22:05 \o/
316 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
317 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
318 SlotsBuffer::VerifySlots(heap, chunk->slots_buffer());
319 }
320 } 364 }
321 #endif 365 #endif
322 366
323 367
324 void MarkCompactCollector::CollectGarbage() { 368 void MarkCompactCollector::CollectGarbage() {
325 // Make sure that Prepare() has been called. The individual steps below will 369 // Make sure that Prepare() has been called. The individual steps below will
326 // update the state as they proceed. 370 // update the state as they proceed.
327 DCHECK(state_ == PREPARE_GC); 371 DCHECK(state_ == PREPARE_GC);
328 372
329 MarkLiveObjects(); 373 MarkLiveObjects();
(...skipping 4131 matching lines...) Expand 10 before | Expand all | Expand 10 after
4461 buffer = allocator->AllocateBuffer(buffer); 4505 buffer = allocator->AllocateBuffer(buffer);
4462 *buffer_address = buffer; 4506 *buffer_address = buffer;
4463 } 4507 }
4464 DCHECK(buffer->HasSpaceForTypedSlot()); 4508 DCHECK(buffer->HasSpaceForTypedSlot());
4465 buffer->Add(reinterpret_cast<ObjectSlot>(type)); 4509 buffer->Add(reinterpret_cast<ObjectSlot>(type));
4466 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); 4510 buffer->Add(reinterpret_cast<ObjectSlot>(addr));
4467 return true; 4511 return true;
4468 } 4512 }
4469 4513
4470 4514
4471 void SlotsBuffer::RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer) {
4472 // Remove entries by replacing them with an old-space slot containing a smi
4473 // that is located in an unmovable page.
4474 const ObjectSlot kRemovedEntry = HeapObject::RawField(
4475 heap->empty_fixed_array(), FixedArrayBase::kLengthOffset);
4476 DCHECK(Page::FromAddress(reinterpret_cast<Address>(kRemovedEntry))
4477 ->NeverEvacuate());
4478
4479 while (buffer != NULL) {
4480 SlotsBuffer::ObjectSlot* slots = buffer->slots_;
4481 intptr_t slots_count = buffer->idx_;
4482
4483 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) {
4484 ObjectSlot slot = slots[slot_idx];
4485 if (!IsTypedSlot(slot)) {
4486 Object* object = *slot;
4487 if ((object->IsHeapObject() && heap->InNewSpace(object)) ||
4488 !heap->mark_compact_collector()->IsSlotInLiveObject(
4489 reinterpret_cast<Address>(slot))) {
4490 slots[slot_idx] = kRemovedEntry;
4491 }
4492 } else {
4493 ++slot_idx;
4494 DCHECK(slot_idx < slots_count);
4495 }
4496 }
4497 buffer = buffer->next();
4498 }
4499 }
4500
4501
4502 void SlotsBuffer::RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer, 4515 void SlotsBuffer::RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer,
4503 Address start_slot, Address end_slot) { 4516 Address start_slot, Address end_slot) {
4504 // Remove entries by replacing them with an old-space slot containing a smi 4517 // Remove entries by replacing them with an old-space slot containing a smi
4505 // that is located in an unmovable page. 4518 // that is located in an unmovable page.
4506 const ObjectSlot kRemovedEntry = HeapObject::RawField( 4519 const ObjectSlot kRemovedEntry = HeapObject::RawField(
4507 heap->empty_fixed_array(), FixedArrayBase::kLengthOffset); 4520 heap->empty_fixed_array(), FixedArrayBase::kLengthOffset);
4508 DCHECK(Page::FromAddress(reinterpret_cast<Address>(kRemovedEntry)) 4521 DCHECK(Page::FromAddress(reinterpret_cast<Address>(kRemovedEntry))
4509 ->NeverEvacuate()); 4522 ->NeverEvacuate());
4510 4523
4511 while (buffer != NULL) { 4524 while (buffer != NULL) {
(...skipping 15 matching lines...) Expand all
4527 } else { 4540 } else {
4528 is_typed_slot = true; 4541 is_typed_slot = true;
4529 DCHECK(slot_idx < slots_count); 4542 DCHECK(slot_idx < slots_count);
4530 } 4543 }
4531 } 4544 }
4532 buffer = buffer->next(); 4545 buffer = buffer->next();
4533 } 4546 }
4534 } 4547 }
4535 4548
4536 4549
4537 void SlotsBuffer::VerifySlots(Heap* heap, SlotsBuffer* buffer) {
4538 while (buffer != NULL) {
4539 SlotsBuffer::ObjectSlot* slots = buffer->slots_;
4540 intptr_t slots_count = buffer->idx_;
4541
4542 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) {
4543 ObjectSlot slot = slots[slot_idx];
4544 if (!IsTypedSlot(slot)) {
4545 Object* object = *slot;
4546 if (object->IsHeapObject()) {
4547 HeapObject* heap_object = HeapObject::cast(object);
4548 CHECK(!heap->InNewSpace(object));
4549 heap->mark_compact_collector()->VerifyIsSlotInLiveObject(
4550 reinterpret_cast<Address>(slot), heap_object);
4551 }
4552 } else {
4553 ++slot_idx;
4554 DCHECK(slot_idx < slots_count);
4555 }
4556 }
4557 buffer = buffer->next();
4558 }
4559 }
4560
4561
4562 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { 4550 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) {
4563 if (RelocInfo::IsCodeTarget(rmode)) { 4551 if (RelocInfo::IsCodeTarget(rmode)) {
4564 return SlotsBuffer::CODE_TARGET_SLOT; 4552 return SlotsBuffer::CODE_TARGET_SLOT;
4565 } else if (RelocInfo::IsCell(rmode)) { 4553 } else if (RelocInfo::IsCell(rmode)) {
4566 return SlotsBuffer::CELL_TARGET_SLOT; 4554 return SlotsBuffer::CELL_TARGET_SLOT;
4567 } else if (RelocInfo::IsEmbeddedObject(rmode)) { 4555 } else if (RelocInfo::IsEmbeddedObject(rmode)) {
4568 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; 4556 return SlotsBuffer::EMBEDDED_OBJECT_SLOT;
4569 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { 4557 } else if (RelocInfo::IsDebugBreakSlot(rmode)) {
4570 return SlotsBuffer::DEBUG_TARGET_SLOT; 4558 return SlotsBuffer::DEBUG_TARGET_SLOT;
4571 } 4559 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
4713 SlotsBuffer* buffer = *buffer_address; 4701 SlotsBuffer* buffer = *buffer_address;
4714 while (buffer != NULL) { 4702 while (buffer != NULL) {
4715 SlotsBuffer* next_buffer = buffer->next(); 4703 SlotsBuffer* next_buffer = buffer->next();
4716 DeallocateBuffer(buffer); 4704 DeallocateBuffer(buffer);
4717 buffer = next_buffer; 4705 buffer = next_buffer;
4718 } 4706 }
4719 *buffer_address = NULL; 4707 *buffer_address = NULL;
4720 } 4708 }
4721 } // namespace internal 4709 } // namespace internal
4722 } // namespace v8 4710 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698