Chromium Code Reviews

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.
Jump to:
View unified diff |
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...)
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_->RecordRelocSlotToNewSpace(host, rinfo, target);
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_->RecordRelocSlotToNewSpace(host, rinfo, target);
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_->RecordRelocSlotToNewSpace(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_->RecordRelocSlotToNewSpace(host, rinfo, cell);
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...)
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_code_to_new_space_ref_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);
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 338 matching lines...)
2799 return CELL_TARGET_SLOT; 2830 return CELL_TARGET_SLOT;
2800 } else if (RelocInfo::IsEmbeddedObject(rmode)) { 2831 } else if (RelocInfo::IsEmbeddedObject(rmode)) {
2801 return EMBEDDED_OBJECT_SLOT; 2832 return EMBEDDED_OBJECT_SLOT;
2802 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { 2833 } else if (RelocInfo::IsDebugBreakSlot(rmode)) {
2803 return DEBUG_TARGET_SLOT; 2834 return DEBUG_TARGET_SLOT;
2804 } 2835 }
2805 UNREACHABLE(); 2836 UNREACHABLE();
2806 return NUMBER_OF_SLOT_TYPES; 2837 return NUMBER_OF_SLOT_TYPES;
2807 } 2838 }
2808 2839
2840 namespace {
2841 void GetAddressAndSlotType(RelocInfo::Mode rmode, RelocInfo* rinfo,
2842 Address& addr, SlotType& slot_type) {
2843 addr = rinfo->pc();
2844 slot_type = SlotTypeForRMode(rmode);
2845 if (rinfo->IsInConstantPool()) {
2846 addr = rinfo->constant_pool_entry_address();
2847 if (RelocInfo::IsCodeTarget(rmode)) {
2848 slot_type = CODE_ENTRY_SLOT;
2849 } else {
2850 DCHECK(RelocInfo::IsEmbeddedObject(rmode));
2851 slot_type = OBJECT_SLOT;
2852 }
2853 }
2854 }
2855 } // namespace
2856
2857 void MarkCompactCollector::RecordRelocSlotToNewSpace(Code* host,
2858 RelocInfo* rinfo,
2859 Object* target) {
2860 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host));
2861 RelocInfo::Mode rmode = rinfo->rmode();
2862 if (heap()->InNewSpace(target)) {
2863 Address addr;
2864 SlotType slot_type;
2865 GetAddressAndSlotType(rmode, rinfo, addr, slot_type);
2866 RememberedSet<OLD_TO_NEW>::InsertTyped(
2867 source_page, reinterpret_cast<Address>(host), slot_type, addr);
2868 }
2869 }
2870
2809 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, 2871 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo,
2810 Object* target) { 2872 Object* target) {
2811 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 2873 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
2812 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); 2874 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host));
2813 RelocInfo::Mode rmode = rinfo->rmode(); 2875 RelocInfo::Mode rmode = rinfo->rmode();
2814 if (target_page->IsEvacuationCandidate() && 2876 if (target_page->IsEvacuationCandidate() &&
2815 (rinfo->host() == NULL || 2877 (rinfo->host() == NULL ||
2816 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { 2878 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) {
2817 Address addr = rinfo->pc(); 2879 Address addr;
2818 SlotType slot_type = SlotTypeForRMode(rmode); 2880 SlotType slot_type;
2819 if (rinfo->IsInConstantPool()) { 2881 GetAddressAndSlotType(rmode, rinfo, addr, slot_type);
2820 addr = rinfo->constant_pool_entry_address();
2821 if (RelocInfo::IsCodeTarget(rmode)) {
2822 slot_type = CODE_ENTRY_SLOT;
2823 } else {
2824 DCHECK(RelocInfo::IsEmbeddedObject(rmode));
2825 slot_type = OBJECT_SLOT;
2826 }
2827 }
2828 RememberedSet<OLD_TO_OLD>::InsertTyped( 2882 RememberedSet<OLD_TO_OLD>::InsertTyped(
2829 source_page, reinterpret_cast<Address>(host), slot_type, addr); 2883 source_page, reinterpret_cast<Address>(host), slot_type, addr);
2830 } 2884 }
2831 } 2885 }
2832 2886
2833 static inline SlotCallbackResult UpdateSlot(Object** slot) { 2887 static inline SlotCallbackResult UpdateSlot(Object** slot) {
2834 Object* obj = reinterpret_cast<Object*>( 2888 Object* obj = reinterpret_cast<Object*>(
2835 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 2889 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
2836 2890
2837 if (obj->IsHeapObject()) { 2891 if (obj->IsHeapObject()) {
(...skipping 587 matching lines...)
3425 memset(free_start, 0xcc, size); 3479 memset(free_start, 0xcc, size);
3426 } 3480 }
3427 freed_bytes = space->UnaccountedFree(free_start, size); 3481 freed_bytes = space->UnaccountedFree(free_start, size);
3428 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3482 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3429 } 3483 }
3430 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); 3484 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3431 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); 3485 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
3432 } 3486 }
3433 3487
3434 void MarkCompactCollector::InvalidateCode(Code* code) { 3488 void MarkCompactCollector::InvalidateCode(Code* code) {
3489 Page* page = Page::FromAddress(code->address());
3490 Address start = code->instruction_start();
3491 Address end = code->address() + code->Size();
3492
3493 RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end);
3494
3435 if (heap_->incremental_marking()->IsCompacting() && 3495 if (heap_->incremental_marking()->IsCompacting() &&
3436 !ShouldSkipEvacuationSlotRecording(code)) { 3496 !ShouldSkipEvacuationSlotRecording(code)) {
3437 DCHECK(compacting_); 3497 DCHECK(compacting_);
3438 3498
3439 // If the object is white than no slots were recorded on it yet. 3499 // If the object is white than no slots were recorded on it yet.
3440 MarkBit mark_bit = Marking::MarkBitFrom(code); 3500 MarkBit mark_bit = Marking::MarkBitFrom(code);
3441 if (Marking::IsWhite(mark_bit)) return; 3501 if (Marking::IsWhite(mark_bit)) return;
3442 3502
3443 // Ignore all slots that might have been recorded in the body of the 3503 // Ignore all slots that might have been recorded in the body of the
3444 // deoptimized code object. Assumption: no slots will be recorded for 3504 // deoptimized code object. Assumption: no slots will be recorded for
3445 // this object after invalidating it. 3505 // 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); 3506 RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end);
3450 RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end);
3451 } 3507 }
3452 } 3508 }
3453 3509
3454 3510
3455 // Return true if the given code is deoptimized or will be deoptimized. 3511 // Return true if the given code is deoptimized or will be deoptimized.
3456 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { 3512 bool MarkCompactCollector::WillBeDeoptimized(Code* code) {
3457 return code->is_optimized_code() && code->marked_for_deoptimization(); 3513 return code->is_optimized_code() && code->marked_for_deoptimization();
3458 } 3514 }
3459 3515
3460 3516
(...skipping 525 matching lines...)
3986 4042
3987 void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) { 4043 void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) {
3988 DCHECK(heap()->gc_state() == Heap::MARK_COMPACT); 4044 DCHECK(heap()->gc_state() == Heap::MARK_COMPACT);
3989 if (is_compacting()) { 4045 if (is_compacting()) {
3990 Code* host = 4046 Code* host =
3991 isolate()->inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer( 4047 isolate()->inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(
3992 pc); 4048 pc);
3993 MarkBit mark_bit = Marking::MarkBitFrom(host); 4049 MarkBit mark_bit = Marking::MarkBitFrom(host);
3994 if (Marking::IsBlack(mark_bit)) { 4050 if (Marking::IsBlack(mark_bit)) {
3995 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 4051 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4052 RecordRelocSlotToNewSpace(host, &rinfo, target);
3996 RecordRelocSlot(host, &rinfo, target); 4053 RecordRelocSlot(host, &rinfo, target);
3997 } 4054 }
3998 } 4055 }
3999 } 4056 }
4000 4057
4001 } // namespace internal 4058 } // namespace internal
4002 } // namespace v8 4059 } // namespace v8
OLDNEW

Powered by Google App Engine