1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HEAP_MARK_COMPACT_INL_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_MARK_COMPACT_INL_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/mark-compact.h" 91b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/heap/remembered-set.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MarkCompactCollector::PushBlack(HeapObject* obj) { 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Marking::IsBlack(Marking::MarkBitFrom(obj))); 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (marking_deque_.Push(obj)) { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size()); 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Marking::BlackToGrey(obj); 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MarkCompactCollector::UnshiftBlack(HeapObject* obj) { 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Marking::IsBlack(Marking::MarkBitFrom(obj))); 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!marking_deque_.Unshift(obj)) { 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::IncrementLiveBytesFromGC(obj, -obj->Size()); 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Marking::BlackToGrey(obj); 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) { 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Marking::MarkBitFrom(obj) == mark_bit); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Marking::IsWhite(mark_bit)) { 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Marking::WhiteToBlack(mark_bit); 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(obj->GetIsolate()->heap()->Contains(obj)); 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushBlack(obj); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MarkCompactCollector::SetMark(HeapObject* obj, MarkBit mark_bit) { 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Marking::IsWhite(mark_bit)); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Marking::MarkBitFrom(obj) == mark_bit); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Marking::WhiteToBlack(mark_bit); 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size()); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool MarkCompactCollector::IsMarked(Object* obj) { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(obj->IsHeapObject()); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* heap_object = HeapObject::cast(obj); 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Marking::IsBlackOrGrey(Marking::MarkBitFrom(heap_object)); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MarkCompactCollector::RecordSlot(HeapObject* object, Object** slot, 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* target) { 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 621b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Page* source_page = Page::FromAddress(reinterpret_cast<Address>(object)); 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_page->IsEvacuationCandidate() && 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !ShouldSkipEvacuationSlotRecording(object)) { 651b268ca467c924004286c97bac133db489cf43d0Ben Murdoch DCHECK(Marking::IsBlackOrGrey(Marking::MarkBitFrom(object))); 661b268ca467c924004286c97bac133db489cf43d0Ben Murdoch RememberedSet<OLD_TO_OLD>::Insert(source_page, 671b268ca467c924004286c97bac133db489cf43d0Ben Murdoch reinterpret_cast<Address>(slot)); 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::AddCandidate(SharedFunctionInfo* shared_info) { 73342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (GetNextCandidate(shared_info) == nullptr) { 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetNextCandidate(shared_info, shared_function_info_candidates_head_); 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_function_info_candidates_head_ = shared_info; 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::AddCandidate(JSFunction* function) { 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function->code() == function->shared()->code()); 8221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (function->next_function_link()->IsUndefined(isolate_)) { 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetNextCandidate(function, jsfunction_candidates_head_); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsfunction_candidates_head_ = function; 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochJSFunction** CodeFlusher::GetNextCandidateSlot(JSFunction* candidate) { 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<JSFunction**>( 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObject::RawField(candidate, JSFunction::kNextFunctionLinkOffset)); 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochJSFunction* CodeFlusher::GetNextCandidate(JSFunction* candidate) { 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* next_candidate = candidate->next_function_link(); 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<JSFunction*>(next_candidate); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::SetNextCandidate(JSFunction* candidate, 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSFunction* next_candidate) { 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch candidate->set_next_function_link(next_candidate, UPDATE_WEAK_WRITE_BARRIER); 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::ClearNextCandidate(JSFunction* candidate, Object* undefined) { 10821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(undefined->IsUndefined(candidate->GetIsolate())); 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch candidate->set_next_function_link(undefined, SKIP_WRITE_BARRIER); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSharedFunctionInfo* CodeFlusher::GetNextCandidate( 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* candidate) { 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* next_candidate = candidate->code()->gc_metadata(); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<SharedFunctionInfo*>(next_candidate); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::SetNextCandidate(SharedFunctionInfo* candidate, 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* next_candidate) { 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch candidate->code()->set_gc_metadata(next_candidate); 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeFlusher::ClearNextCandidate(SharedFunctionInfo* candidate) { 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER); 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <LiveObjectIterationMode T> 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* LiveObjectIterator<T>::Next() { 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (!it_.Done()) { 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObject* object = nullptr; 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (current_cell_ != 0) { 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t trailing_zeros = base::bits::CountTrailingZeros32(current_cell_); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address addr = cell_base_ + trailing_zeros * kPointerSize; 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the first bit of the found object.. 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_cell_ &= ~(1u << trailing_zeros); 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t second_bit_index = 0; 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (trailing_zeros < Bitmap::kBitIndexMask) { 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch second_bit_index = 1u << (trailing_zeros + 1); 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch second_bit_index = 0x1; 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The overlapping case; there has to exist a cell after the current 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // cell. 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!it_.Done()); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it_.Advance(); 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cell_base_ = it_.CurrentCellBase(); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_cell_ = *it_.CurrentCell(); 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (T == kBlackObjects && (current_cell_ & second_bit_index)) { 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object = HeapObject::FromAddress(addr); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (T == kGreyObjects && !(current_cell_ & second_bit_index)) { 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object = HeapObject::FromAddress(addr); 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (T == kAllLiveObjects) { 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object = HeapObject::FromAddress(addr); 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1611b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the second bit of the found object. 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_cell_ &= ~second_bit_index; 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We found a live object. 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (object != nullptr) break; 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current_cell_ == 0) { 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!it_.Done()) { 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it_.Advance(); 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cell_base_ = it_.CurrentCellBase(); 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_cell_ = *it_.CurrentCell(); 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (object != nullptr) return object; 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_HEAP_MARK_COMPACT_INL_H_ 184