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

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

Issue 2045263002: [heap] Avoid the use of cells to point from code to new-space objects. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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
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/base/sys-info.h" 9 #include "src/base/sys-info.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot), 1556 RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot),
1557 nullptr, CODE_ENTRY_SLOT, 1557 nullptr, CODE_ENTRY_SLOT,
1558 code_entry_slot); 1558 code_entry_slot);
1559 } 1559 }
1560 } 1560 }
1561 1561
1562 inline void VisitCodeTarget(RelocInfo* rinfo) final { 1562 inline void VisitCodeTarget(RelocInfo* rinfo) final {
1563 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); 1563 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
1564 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1564 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1565 Code* host = rinfo->host(); 1565 Code* host = rinfo->host();
1566 collector_->heap()->RecordWriteIntoCode(host, rinfo, target);
ulan 2016/06/09 14:45:22 Replace it with a comment that we don't need to re
ahaas 2016/06/10 11:00:34 done.
1566 collector_->RecordRelocSlot(host, rinfo, target); 1567 collector_->RecordRelocSlot(host, rinfo, target);
1567 } 1568 }
1568 1569
1569 inline void VisitDebugTarget(RelocInfo* rinfo) final { 1570 inline void VisitDebugTarget(RelocInfo* rinfo) final {
1570 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 1571 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
1571 rinfo->IsPatchedDebugBreakSlotSequence()); 1572 rinfo->IsPatchedDebugBreakSlotSequence());
1572 Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); 1573 Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
1573 Code* host = rinfo->host(); 1574 Code* host = rinfo->host();
1575 collector_->heap()->RecordWriteIntoCode(host, rinfo, target);
ulan 2016/06/09 14:45:22 ditto
ahaas 2016/06/10 11:00:34 done.
1574 collector_->RecordRelocSlot(host, rinfo, target); 1576 collector_->RecordRelocSlot(host, rinfo, target);
1575 } 1577 }
1576 1578
1577 inline void VisitEmbeddedPointer(RelocInfo* rinfo) final { 1579 inline void VisitEmbeddedPointer(RelocInfo* rinfo) final {
1578 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 1580 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
1579 HeapObject* object = HeapObject::cast(rinfo->target_object()); 1581 HeapObject* object = HeapObject::cast(rinfo->target_object());
1580 Code* host = rinfo->host(); 1582 Code* host = rinfo->host();
1583 collector_->heap()->RecordWriteIntoCode(host, rinfo, object);
1581 collector_->RecordRelocSlot(host, rinfo, object); 1584 collector_->RecordRelocSlot(host, rinfo, object);
1582 } 1585 }
1583 1586
1584 inline void VisitCell(RelocInfo* rinfo) final { 1587 inline void VisitCell(RelocInfo* rinfo) final {
1585 DCHECK(rinfo->rmode() == RelocInfo::CELL); 1588 DCHECK(rinfo->rmode() == RelocInfo::CELL);
1586 Cell* cell = rinfo->target_cell(); 1589 Cell* cell = rinfo->target_cell();
1587 Code* host = rinfo->host(); 1590 Code* host = rinfo->host();
1591 collector_->heap()->RecordWriteIntoCode(host, rinfo, cell);
ulan 2016/06/09 14:45:22 ditto
ahaas 2016/06/10 11:00:34 done.
1588 collector_->RecordRelocSlot(host, rinfo, cell); 1592 collector_->RecordRelocSlot(host, rinfo, cell);
1589 } 1593 }
1590 1594
1591 // Entries that will never move. 1595 // Entries that will never move.
1592 inline void VisitCodeAgeSequence(RelocInfo* rinfo) final { 1596 inline void VisitCodeAgeSequence(RelocInfo* rinfo) final {
1593 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); 1597 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
1594 Code* stub = rinfo->code_age_stub(); 1598 Code* stub = rinfo->code_age_stub();
1595 USE(stub); 1599 USE(stub);
1596 DCHECK(!Page::FromAddress(stub->address())->IsEvacuationCandidate()); 1600 DCHECK(!Page::FromAddress(stub->address())->IsEvacuationCandidate());
1597 } 1601 }
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 DependentCode* list_head) { 2445 DependentCode* list_head) {
2442 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_DEPENDENT_CODE); 2446 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_DEPENDENT_CODE);
2443 Isolate* isolate = this->isolate(); 2447 Isolate* isolate = this->isolate();
2444 DependentCode* current = list_head; 2448 DependentCode* current = list_head;
2445 while (current->length() > 0) { 2449 while (current->length() > 0) {
2446 have_code_to_deoptimize_ |= current->MarkCodeForDeoptimization( 2450 have_code_to_deoptimize_ |= current->MarkCodeForDeoptimization(
2447 isolate, DependentCode::kWeakCodeGroup); 2451 isolate, DependentCode::kWeakCodeGroup);
2448 current = current->next_link(); 2452 current = current->next_link();
2449 } 2453 }
2450 2454
2455 {
2456 ArrayList* list = heap_->weak_new_space_object_to_code_list();
2457 int counter = 0;
2458 for (int i = 0; i < list->Length(); i += 2) {
2459 WeakCell* obj = WeakCell::cast(list->Get(i));
2460 WeakCell* dep = WeakCell::cast(list->Get(i + 1));
2461 if (obj->cleared() || dep->cleared()) {
2462 if (!dep->cleared()) {
2463 Code* code = Code::cast(dep->value());
2464 if (!code->marked_for_deoptimization()) {
2465 DependentCode::SetMarkedForDeoptimization(
2466 code, DependentCode::DependencyGroup::kWeakCodeGroup);
2467 code->InvalidateEmbeddedObjects();
2468 have_code_to_deoptimize_ = true;
2469 }
2470 }
2471 } else {
2472 list->Set(counter, obj, SKIP_WRITE_BARRIER);
titzer 2016/06/09 11:10:21 I don't understand why this is a SKIP_WRITE_BARRIE
ahaas 2016/06/09 11:20:40 We skip the write barrier because this code is exe
ulan 2016/06/09 14:45:22 Yes, the barrier will bailout because marking is f
titzer 2016/06/10 13:27:06 Let's add a comment to document this.
2473 RecordSlot(list, list->Slot(counter), obj);
2474 counter++;
2475 list->Set(counter, dep, SKIP_WRITE_BARRIER);
2476 RecordSlot(list, list->Slot(counter), dep);
2477 counter++;
2478 }
2479 }
2480 }
2481
2451 WeakHashTable* table = heap_->weak_object_to_code_table(); 2482 WeakHashTable* table = heap_->weak_object_to_code_table();
2452 uint32_t capacity = table->Capacity(); 2483 uint32_t capacity = table->Capacity();
2453 for (uint32_t i = 0; i < capacity; i++) { 2484 for (uint32_t i = 0; i < capacity; i++) {
2454 uint32_t key_index = table->EntryToIndex(i); 2485 uint32_t key_index = table->EntryToIndex(i);
2455 Object* key = table->get(key_index); 2486 Object* key = table->get(key_index);
2456 if (!table->IsKey(isolate, key)) continue; 2487 if (!table->IsKey(isolate, key)) continue;
2457 uint32_t value_index = table->EntryToValueIndex(i); 2488 uint32_t value_index = table->EntryToValueIndex(i);
2458 Object* value = table->get(value_index); 2489 Object* value = table->get(value_index);
2459 DCHECK(key->IsWeakCell()); 2490 DCHECK(key->IsWeakCell());
2460 if (WeakCell::cast(key)->cleared()) { 2491 if (WeakCell::cast(key)->cleared()) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 HeapObject* undefined = heap()->undefined_value(); 2816 HeapObject* undefined = heap()->undefined_value();
2786 Object* obj = heap()->encountered_transition_arrays(); 2817 Object* obj = heap()->encountered_transition_arrays();
2787 while (obj != Smi::FromInt(0)) { 2818 while (obj != Smi::FromInt(0)) {
2788 TransitionArray* array = TransitionArray::cast(obj); 2819 TransitionArray* array = TransitionArray::cast(obj);
2789 obj = array->next_link(); 2820 obj = array->next_link();
2790 array->set_next_link(undefined, SKIP_WRITE_BARRIER); 2821 array->set_next_link(undefined, SKIP_WRITE_BARRIER);
2791 } 2822 }
2792 heap()->set_encountered_transition_arrays(Smi::FromInt(0)); 2823 heap()->set_encountered_transition_arrays(Smi::FromInt(0));
2793 } 2824 }
2794 2825
2795 static inline SlotType SlotTypeForRMode(RelocInfo::Mode rmode) {
2796 if (RelocInfo::IsCodeTarget(rmode)) {
2797 return CODE_TARGET_SLOT;
2798 } else if (RelocInfo::IsCell(rmode)) {
2799 return CELL_TARGET_SLOT;
2800 } else if (RelocInfo::IsEmbeddedObject(rmode)) {
2801 return EMBEDDED_OBJECT_SLOT;
2802 } else if (RelocInfo::IsDebugBreakSlot(rmode)) {
2803 return DEBUG_TARGET_SLOT;
2804 }
2805 UNREACHABLE();
2806 return NUMBER_OF_SLOT_TYPES;
2807 }
2808
2809 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, 2826 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo,
2810 Object* target) { 2827 Object* target) {
2811 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 2828 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
2812 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); 2829 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host));
2813 RelocInfo::Mode rmode = rinfo->rmode();
2814 if (target_page->IsEvacuationCandidate() && 2830 if (target_page->IsEvacuationCandidate() &&
2815 (rinfo->host() == NULL || 2831 (rinfo->host() == NULL ||
2816 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { 2832 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) {
2833 RelocInfo::Mode rmode = rinfo->rmode();
2817 Address addr = rinfo->pc(); 2834 Address addr = rinfo->pc();
2818 SlotType slot_type = SlotTypeForRMode(rmode); 2835 SlotType slot_type = SlotTypeForRelocInfoMode(rmode);
2819 if (rinfo->IsInConstantPool()) { 2836 if (rinfo->IsInConstantPool()) {
2820 addr = rinfo->constant_pool_entry_address(); 2837 addr = rinfo->constant_pool_entry_address();
2821 if (RelocInfo::IsCodeTarget(rmode)) { 2838 if (RelocInfo::IsCodeTarget(rmode)) {
2822 slot_type = CODE_ENTRY_SLOT; 2839 slot_type = CODE_ENTRY_SLOT;
2823 } else { 2840 } else {
2824 DCHECK(RelocInfo::IsEmbeddedObject(rmode)); 2841 DCHECK(RelocInfo::IsEmbeddedObject(rmode));
2825 slot_type = OBJECT_SLOT; 2842 slot_type = OBJECT_SLOT;
2826 } 2843 }
2827 } 2844 }
2828 RememberedSet<OLD_TO_OLD>::InsertTyped( 2845 RememberedSet<OLD_TO_OLD>::InsertTyped(
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
3425 memset(free_start, 0xcc, size); 3442 memset(free_start, 0xcc, size);
3426 } 3443 }
3427 freed_bytes = space->UnaccountedFree(free_start, size); 3444 freed_bytes = space->UnaccountedFree(free_start, size);
3428 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3445 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3429 } 3446 }
3430 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); 3447 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3431 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); 3448 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
3432 } 3449 }
3433 3450
3434 void MarkCompactCollector::InvalidateCode(Code* code) { 3451 void MarkCompactCollector::InvalidateCode(Code* code) {
3452 Page* page = Page::FromAddress(code->address());
3453 Address start = code->instruction_start();
3454 Address end = code->address() + code->Size();
3455
3456 RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end);
3457
3435 if (heap_->incremental_marking()->IsCompacting() && 3458 if (heap_->incremental_marking()->IsCompacting() &&
3436 !ShouldSkipEvacuationSlotRecording(code)) { 3459 !ShouldSkipEvacuationSlotRecording(code)) {
3437 DCHECK(compacting_); 3460 DCHECK(compacting_);
3438 3461
3439 // If the object is white than no slots were recorded on it yet. 3462 // If the object is white than no slots were recorded on it yet.
3440 MarkBit mark_bit = Marking::MarkBitFrom(code); 3463 MarkBit mark_bit = Marking::MarkBitFrom(code);
3441 if (Marking::IsWhite(mark_bit)) return; 3464 if (Marking::IsWhite(mark_bit)) return;
3442 3465
3443 // Ignore all slots that might have been recorded in the body of the 3466 // Ignore all slots that might have been recorded in the body of the
3444 // deoptimized code object. Assumption: no slots will be recorded for 3467 // deoptimized code object. Assumption: no slots will be recorded for
3445 // this object after invalidating it. 3468 // this object after invalidating it.
3446 Page* page = Page::FromAddress(code->address());
3447 Address start = code->instruction_start();
3448 Address end = code->address() + code->Size();
3449 RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end); 3469 RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end);
3450 RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end);
3451 } 3470 }
3452 } 3471 }
3453 3472
3454 3473
3455 // Return true if the given code is deoptimized or will be deoptimized. 3474 // Return true if the given code is deoptimized or will be deoptimized.
3456 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { 3475 bool MarkCompactCollector::WillBeDeoptimized(Code* code) {
3457 return code->is_optimized_code() && code->marked_for_deoptimization(); 3476 return code->is_optimized_code() && code->marked_for_deoptimization();
3458 } 3477 }
3459 3478
3460 3479
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3986 4005
3987 void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) { 4006 void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) {
3988 DCHECK(heap()->gc_state() == Heap::MARK_COMPACT); 4007 DCHECK(heap()->gc_state() == Heap::MARK_COMPACT);
3989 if (is_compacting()) { 4008 if (is_compacting()) {
3990 Code* host = 4009 Code* host =
3991 isolate()->inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer( 4010 isolate()->inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(
3992 pc); 4011 pc);
3993 MarkBit mark_bit = Marking::MarkBitFrom(host); 4012 MarkBit mark_bit = Marking::MarkBitFrom(host);
3994 if (Marking::IsBlack(mark_bit)) { 4013 if (Marking::IsBlack(mark_bit)) {
3995 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 4014 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4015 heap()->RecordWriteIntoCode(host, &rinfo, target);
ulan 2016/06/09 14:45:22 ditto
ahaas 2016/06/10 11:00:34 done.
3996 RecordRelocSlot(host, &rinfo, target); 4016 RecordRelocSlot(host, &rinfo, target);
3997 } 4017 }
3998 } 4018 }
3999 } 4019 }
4000 4020
4001 } // namespace internal 4021 } // namespace internal
4002 } // namespace v8 4022 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698