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_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_MARK_COMPACT_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include <deque> 9bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 11c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/platform/condition-variable.h" 12c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/cancelable-task.h" 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/heap/marking.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/spaces.h" 15109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/heap/store-buffer.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Callback function, returns whether an object is alive. The heap size 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// of the object is returned in size. It optionally updates the offset 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to the first live object in the page (only used for old and map objects). 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Callback function to mark an object in a given heap. 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object); 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations. 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher; 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector; 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingVisitor; 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RootMarkingVisitor; 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ObjectMarking : public AllStatic { 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static MarkBit MarkBitFrom(Address addr)) { 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk* p = MemoryChunk::FromAddress(addr); 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(addr)); 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) { 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MarkBitFrom(reinterpret_cast<Address>(obj)); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Marking::ObjectColor Color(HeapObject* obj) { 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Marking::Color(ObjectMarking::MarkBitFrom(obj)); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectMarking); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Marking deque for tracing live objects. 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingDeque { 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch explicit MarkingDeque(Heap* heap) 58c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : backing_store_(nullptr), 59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch backing_store_committed_size_(0), 60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch array_(nullptr), 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_(0), 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bottom_(0), 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mask_(0), 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch overflowed_(false), 65c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch in_use_(false), 66c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uncommit_task_pending_(false), 67c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch heap_(heap) {} 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 69c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void SetUp(); 70c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void TearDown(); 71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Ensures that the marking deque is committed and will stay committed until 73c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // StopUsing() is called. 74c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StartUsing(); 75c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StopUsing(); 76c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void Clear(); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsEmpty() { return top_ == bottom_; } 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed() const { return overflowed_; } 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearOverflowed() { overflowed_ = false; } 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetOverflowed() { overflowed_ = true; } 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push the object on the marking stack if there is room, otherwise mark the 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // deque as overflowed and wait for a rescan of the heap. 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(bool Push(HeapObject* object)) { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[top_] = object; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ + 1) & mask_); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(HeapObject* Pop()) { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsEmpty()); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ - 1) & mask_); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object = array_[top_]; 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unshift the object into the marking stack if there is room, otherwise mark 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the deque as overflowed and wait for a rescan of the heap. 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(bool Unshift(HeapObject* object)) { 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bottom_ = ((bottom_ - 1) & mask_); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[bottom_] = object; 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array() { return array_; } 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom() { return bottom_; } 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top() { return top_; } 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask() { return mask_; } 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_top(int top) { top_ = top; } 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 131c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // This task uncommits the marking_deque backing store if 132c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // markin_deque->in_use_ is false. 133c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch class UncommitTask : public CancelableTask { 134c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch public: 135c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch explicit UncommitTask(Isolate* isolate, MarkingDeque* marking_deque) 136c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : CancelableTask(isolate), marking_deque_(marking_deque) {} 137c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 138c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch private: 139c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // CancelableTask override. 140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void RunInternal() override { 141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch base::LockGuard<base::Mutex> guard(&marking_deque_->mutex_); 142c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!marking_deque_->in_use_) { 143c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch marking_deque_->Uncommit(); 144c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 145c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch marking_deque_->uncommit_task_pending_ = false; 146c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 147c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch MarkingDeque* marking_deque_; 149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DISALLOW_COPY_AND_ASSIGN(UncommitTask); 150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch }; 151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const size_t kMaxSize = 4 * MB; 153c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const size_t kMinSize = 256 * KB; 154c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 155c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Must be called with mutex lock. 156c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void EnsureCommitted(); 157c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 158c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Must be called with mutex lock. 159c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void Uncommit(); 160c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 161c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Must be called with mutex lock. 162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StartUncommitTask(); 163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch base::Mutex mutex_; 165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 166c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch base::VirtualMemory* backing_store_; 167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch size_t backing_store_committed_size_; 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array_; 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // array_[(top - 1) & mask_] is the top element in the deque. The Deque is 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // empty when top_ == bottom_. It is full when top_ + 1 == bottom 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (mod mask + 1). 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top_; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom_; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask_; 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed_; 176c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // in_use_ == true after taking mutex lock implies that the marking deque is 177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // committed and will stay committed at least until in_use_ == false. 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_use_; 179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool uncommit_task_pending_; 180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Heap* heap_; 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(MarkingDeque); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CodeFlusher collects candidates for code flushing during marking and 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// processes those candidates after marking has completed in order to 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// reset those functions referencing code objects that would otherwise 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// be unreachable. Code objects can be referenced in two ways: 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - SharedFunctionInfo references unoptimized code. 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - JSFunction references either unoptimized or optimized code. 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We are not allowed to flush unoptimized code for functions that got 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// optimized or inlined into optimized code, because we might bailout 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// into the unoptimized code again during deoptimization. 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher { 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CodeFlusher(Isolate* isolate) 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_(isolate), 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsfunction_candidates_head_(nullptr), 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_function_info_candidates_head_(nullptr) {} 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void AddCandidate(SharedFunctionInfo* shared_info); 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void AddCandidate(JSFunction* function); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(SharedFunctionInfo* shared_info); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(JSFunction* function); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessCandidates() { 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessSharedFunctionInfoCandidates(); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessJSFunctionCandidates(); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IteratePointersToFromSpace(ObjectVisitor* v); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessJSFunctionCandidates(); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessSharedFunctionInfoCandidates(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline JSFunction** GetNextCandidateSlot(JSFunction* candidate); 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline JSFunction* GetNextCandidate(JSFunction* candidate); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetNextCandidate(JSFunction* candidate, 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSFunction* next_candidate); 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void ClearNextCandidate(JSFunction* candidate, 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* undefined); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline SharedFunctionInfo* GetNextCandidate( 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* candidate); 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetNextCandidate(SharedFunctionInfo* candidate, 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* next_candidate); 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void ClearNextCandidate(SharedFunctionInfo* candidate); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* jsfunction_candidates_head_; 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared_function_info_candidates_head_; 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(CodeFlusher); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Defined in isolate.h. 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ThreadLocalTop; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass MarkBitCellIterator BASE_EMBEDDED { 2443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch public: 2453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { 2463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch last_cell_index_ = Bitmap::IndexToCell(Bitmap::CellAlignIndex( 2473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch chunk_->AddressToMarkbitIndex(chunk_->area_end()))); 2483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cell_base_ = chunk_->area_start(); 2493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cell_index_ = Bitmap::IndexToCell( 2503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bitmap::CellAlignIndex(chunk_->AddressToMarkbitIndex(cell_base_))); 2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cells_ = chunk_->markbits()->cells(); 2523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline bool Done() { return cell_index_ == last_cell_index_; } 2553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline bool HasNext() { return cell_index_ < last_cell_index_ - 1; } 2573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline MarkBit::CellType* CurrentCell() { 2593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 2603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 2613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return &cells_[cell_index_]; 2623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline Address CurrentCellBase() { 2653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 2663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 2673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return cell_base_; 2683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Advance() { 2713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cell_index_++; 272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cell_base_ += Bitmap::kBitsPerCell * kPointerSize; 273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline bool Advance(unsigned int new_cell_index) { 276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (new_cell_index != cell_index_) { 277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_GT(new_cell_index, cell_index_); 278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_LE(new_cell_index, last_cell_index_); 279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unsigned int diff = new_cell_index - cell_index_; 280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cell_index_ = new_cell_index; 281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cell_base_ += diff * (Bitmap::kBitsPerCell * kPointerSize); 282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 2853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Return the next mark bit cell. If there is no next it returns 0; 2883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline MarkBit::CellType PeekNext() { 2893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasNext()) { 2903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return cells_[cell_index_ + 1]; 2913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return 0; 2933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch private: 2963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemoryChunk* chunk_; 2973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MarkBit::CellType* cells_; 2983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch unsigned int last_cell_index_; 2993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch unsigned int cell_index_; 3003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Address cell_base_; 3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}; 3023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Grey objects can happen on black pages when black objects transition to 3043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// grey e.g. when calling RecordWrites on them. 3053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochenum LiveObjectIterationMode { 3063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kBlackObjects, 3073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kGreyObjects, 3083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kAllLiveObjects 3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}; 3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochtemplate <LiveObjectIterationMode T> 3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass LiveObjectIterator BASE_EMBEDDED { 3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch public: 3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch explicit LiveObjectIterator(MemoryChunk* chunk) 3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch : chunk_(chunk), 3163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch it_(chunk_), 3173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cell_base_(it_.CurrentCellBase()), 3183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch current_cell_(*it_.CurrentCell()) { 3193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HeapObject* Next(); 3223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch private: 324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch inline Heap* heap() { return chunk_->heap(); } 325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemoryChunk* chunk_; 3273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MarkBitCellIterator it_; 3283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Address cell_base_; 3293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MarkBit::CellType current_cell_; 3303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}; 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochenum PageEvacuationMode { NEW_TO_NEW, NEW_TO_OLD }; 333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------------------------------------------------------------------- 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Mark-Compact collector 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 3383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch class Evacuator; 3393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 340bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch class Sweeper { 341bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public: 342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch class SweeperTask; 343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch enum FreeListRebuildingMode { REBUILD_FREE_LIST, IGNORE_FREE_LIST }; 345bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; 346c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch enum ClearOldToNewSlotsMode { 347c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DO_NOT_CLEAR, 348c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CLEAR_REGULAR_SLOTS, 349c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CLEAR_TYPED_SLOTS 350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch }; 351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch typedef std::deque<Page*> SweepingList; 353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch typedef List<Page*> SweptList; 354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static int RawSweep(Page* p, FreeListRebuildingMode free_list_mode, 356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FreeSpaceTreatmentMode free_space_mode); 357bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 358bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch explicit Sweeper(Heap* heap) 359bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : heap_(heap), 360bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch pending_sweeper_tasks_semaphore_(0), 361bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch sweeping_in_progress_(false), 362bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch num_sweeping_tasks_(0) {} 363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool sweeping_in_progress() { return sweeping_in_progress_; } 365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void AddPage(AllocationSpace space, Page* page); 367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int ParallelSweepSpace(AllocationSpace identity, int required_freed_bytes, 369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int max_pages = 0); 37013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int ParallelSweepPage(Page* page, AllocationSpace identity); 371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // After calling this function sweeping is considered to be in progress 373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // and the main thread can sweep lazily, but the background sweeper tasks 374c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // are not running yet. 375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void StartSweeping(); 376c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StartSweeperTasks(); 377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void EnsureCompleted(); 37813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void EnsureNewSpaceCompleted(); 379c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool AreSweeperTasksRunning(); 380c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool IsSweepingCompleted(AllocationSpace space); 381bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void SweepOrWaitUntilSweepingCompleted(Page* page); 382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 383bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void AddSweptPageSafe(PagedSpace* space, Page* page); 384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Page* GetSweptPageSafe(PagedSpace* space); 385bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 386bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch private: 387bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static const int kAllocationSpaces = LAST_PAGED_SPACE + 1; 388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 389c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static ClearOldToNewSlotsMode GetClearOldToNewSlotsMode(Page* p); 390c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 391bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch template <typename Callback> 392bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void ForAllSweepingSpaces(Callback callback) { 393bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (int i = 0; i < kAllocationSpaces; i++) { 394bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch callback(static_cast<AllocationSpace>(i)); 395bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 396bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 397bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Page* GetSweepingPageSafe(AllocationSpace space); 399bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void AddSweepingPageSafe(AllocationSpace space, Page* page); 400bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 401bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void PrepareToBeSweptPage(AllocationSpace space, Page* page); 402bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 403bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Heap* heap_; 404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch base::Semaphore pending_sweeper_tasks_semaphore_; 405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch base::Mutex mutex_; 406bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SweptList swept_list_[kAllocationSpaces]; 407bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SweepingList sweeping_list_[kAllocationSpaces]; 408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool sweeping_in_progress_; 40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::AtomicNumber<intptr_t> num_sweeping_tasks_; 410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch }; 411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum IterationMode { 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kKeepMarking, 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kClearMarkbits, 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize(); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetUp(); 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TearDown(); 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectEvacuationCandidates(PagedSpace* space); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddEvacuationCandidate(Page* p); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prepares for GC by resetting relocation info in old and map spaces and 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // choosing spaces to compact. 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Prepare(); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a global garbage collection. 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectGarbage(); 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 434c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool StartCompaction(); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortCompaction(); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks whether performing mark-compact collection. 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool in_use() { return state_ > PREPARE_GC; } 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; } 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine type of object and emit deletion log event. 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate); 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distinguishable invalid map encodings (for single word and multiple words) 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that indicate free regions. 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kSingleFreeEncoding = 0; 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kMultiFreeEncoding = 1; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool IsMarked(Object* obj); 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsUnmarkedHeapObjectWithHeap(Heap* heap, Object** p); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Heap* heap() const { return heap_; } 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Isolate* isolate() const; 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeFlusher* code_flusher() { return code_flusher_; } 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; } 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VerifyValidStoreAndSlotsBufferEntries(); 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyMarkbitsAreClean(); 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(PagedSpace* space); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(NewSpace* space); 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyWeakEmbeddedObjectsInCode(); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyOmittedMapChecks(); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) { 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(host)) 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->ShouldSkipEvacuationSlotRecording(); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static inline bool IsOnEvacuationCandidate(HeapObject* obj) { 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(obj)) 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->IsEvacuationCandidate(); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void RecordRelocSlot(Code* host, RelocInfo* rinfo, Object* target); 4813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void RecordCodeEntrySlot(HeapObject* host, Address slot, Code* target); 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordCodeTargetPatch(Address pc, Code* target); 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void RecordSlot(HeapObject* object, Object** slot, Object* target)); 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void ForceRecordSlot(HeapObject* object, Object** slot, 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* target)); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateSlots(SlotsBuffer* buffer); 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateSlotsRecordedIn(SlotsBuffer* buffer); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvalidateCode(Code* code); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearMarkbits(); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_compacting() const { return compacting_; } 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingParity marking_parity() { return marking_parity_; } 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensures that sweeping is finished. 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: Can only be called safely from main thread. 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnsureSweepingCompleted(); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Help out in sweeping the corresponding space and refill memory that has 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // been regained. 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: Thread-safe. 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SweepAndRefill(CompactionSpace* space); 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if sweeping is in progress right now on any space. 510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool sweeping_in_progress() { return sweeper().sweeping_in_progress(); } 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_evacuation(bool evacuation) { evacuation_ = evacuation; } 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool evacuation() const { return evacuation_; } 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for processing weak references in a full collection. We need 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to artificially keep AllocationSites alive for a time. 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkAllocationSite(AllocationSite* site); 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark objects in implicit references groups if their parent object 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // is marked. 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkImplicitRefGroups(MarkObjectFunction mark_object); 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MarkingDeque* marking_deque() { return &marking_deque_; } 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Sweeper& sweeper() { return sweeper_; } 527bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 529c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch template <PageEvacuationMode mode> 530bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch class EvacuateNewSpacePageVisitor; 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateNewSpaceVisitor; 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateOldSpaceVisitor; 533bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch class EvacuateRecordOnlyVisitor; 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateVisitorBase; 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class HeapObjectVisitor; 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch class ObjectStatsVisitor; 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkCompactCollector(Heap* heap); 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WillBeDeoptimized(Code* code); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void ComputeEvacuationHeuristics(size_t area_size, 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* target_fragmentation_percent, 544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch size_t* max_evacuated_bytes); 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void VisitAllObjects(HeapObjectVisitor* visitor); 547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void RecordObjectStats(); 549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finishes GC, performs heap verification if enabled. 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Finish(); 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------------------------------------------- 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Phase 1: Marking live objects. 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before: The heap has been prepared for garbage collection by 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MarkCompactCollector::Prepare() and is otherwise in its 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // normal state. 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After: Live objects are marked and non-live objects are unmarked. 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class CodeMarkingVisitor; 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class IncrementalMarkingMarkingVisitor; 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class MarkCompactMarkingVisitor; 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class MarkingVisitor; 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class RecordMigratedSlotVisitor; 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class RootMarkingVisitor; 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class SharedFunctionInfoMarkingVisitor; 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark code objects that are active on the stack to prevent them 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from being flushed. 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareForCodeFlushing(); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marking operations for objects reachable from roots. 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkLiveObjects(); 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Pushes a black object onto the marking stack and accounts for live bytes. 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that this assumes live bytes have not yet been counted. 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void PushBlack(HeapObject* obj)); 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unshifts a black object into the marking stack and accounts for live bytes. 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that this assumes lives bytes have already been counted. 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void UnshiftBlack(HeapObject* obj)); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black and pushes it on the marking stack. 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black assuming that it is not yet marked. 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the heap roots and all objects reachable from them. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkRoots(RootMarkingVisitor* visitor); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the string table specially. References to internalized strings from 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the string table are weak. 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkStringTable(RootMarkingVisitor* visitor); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessMarkingDeque(); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. This respects references only considered in 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the final atomic marking pause including the following: 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Processing of objects reachable through Harmony WeakMaps. 610bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // - Objects reachable due to host application logic like object groups, 611bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // implicit references' groups, or embedder heap tracing. 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ProcessEphemeralMarking(ObjectVisitor* visitor, 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool only_process_harmony_weak_collections); 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the call-site of the top optimized code was not prepared for 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deoptimization, then treat the maps in the code as strong pointers, 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // otherwise a map can die and deoptimize the code. 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessTopOptimizedFrame(ObjectVisitor* visitor); 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Collects a list of dependent code from maps embedded in optimize code. 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode* DependentCodeListFromNonLiveMaps(); 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack. This function empties the marking stack, but may leave 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflowed objects in the heap, in which case the marking stack's 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflow flag will be set. 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmptyMarkingDeque(); 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Refill the marking stack with overflowed objects from the heap. This 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function either leaves the marking stack full or clears the overflow 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // flag on the marking stack. 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RefillMarkingDeque(); 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Helper methods for refilling the marking stack by discovering grey objects 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // on various pages of the heap. Used by {RefillMarkingDeque} only. 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class T> 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsWithIterator(T* it); 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsOnPage(MemoryChunk* p); 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsInSpace(PagedSpace* space); 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsInNewSpace(); 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Callback function for telling whether the object *p is an unmarked 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap object. 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsUnmarkedHeapObject(Object** p); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear non-live references in weak cells, transition and descriptor arrays, 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and deoptimize dependent code of non-live maps. 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLiveReferences(); 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkDependentCodeForDeoptimization(DependentCode* list); 650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find non-live targets of simple transitions in the given list. Clear 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // transitions to non-live targets and if needed trim descriptors arrays. 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearSimpleMapTransitions(Object* non_live_map_list); 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearSimpleMapTransition(Map* map, Map* dead_transition); 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compact every array in the global list of transition arrays and 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // trim the corresponding descriptor array if a transition target is non-live. 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearFullMapTransitions(); 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CompactTransitionArray(Map* map, TransitionArray* transitions, 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DescriptorArray* descriptors); 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TrimDescriptorArray(Map* map, DescriptorArray* descriptors); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrimEnumCache(Map* map, DescriptorArray* descriptors); 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark all values associated with reachable keys in weak collections 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // encountered so far. This might push new object or even new weak maps onto 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the marking stack. 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessWeakCollections(); 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After all reachable objects have been marked those weak map entries 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with an unreachable key are removed from all encountered weak maps. 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The linked list of all encountered weak maps is destroyed. 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearWeakCollections(); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to remove all encountered weak maps from the list of weak 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // collections when incremental marking is aborted. 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortWeakCollections(); 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearWeakCells(Object** non_live_map_list, 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode** dependent_code_list); 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AbortWeakCells(); 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AbortTransitionArrays(); 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 682c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Starts sweeping of spaces by contributing on the main thread and setting 683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // up other pages for sweeping. Does not start sweeper tasks. 684c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StartSweepSpaces(); 685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StartSweepSpace(PagedSpace* space); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvacuateNewSpacePrologue(); 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvacuatePagesInParallel(); 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The number of parallel compaction tasks, including the main thread. 692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int NumberOfParallelCompactionTasks(int pages, intptr_t live_bytes); 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuateNewSpaceAndCandidates(); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdatePointersAfterEvacuation(); 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Iterates through all live objects on a page using marking information. 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns whether all objects have successfully been visited. 700bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch template <class Visitor> 701bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool VisitLiveObjects(MemoryChunk* page, Visitor* visitor, 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IterationMode mode); 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecomputeLiveBytes(MemoryChunk* page); 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ReleaseEvacuationCandidates(); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MarkObjectVisitor; 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitObject(HeapObject* obj); 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class UnmarkObjectVisitor; 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void UnmarkObject(HeapObject* obj); 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 719bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch base::Semaphore page_parallel_job_semaphore_; 720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#ifdef DEBUG 722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch enum CollectorState { 723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IDLE, 724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PREPARE_GC, 725bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MARK_LIVE_OBJECTS, 726bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SWEEP_SPACES, 727bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ENCODE_FORWARDING_ADDRESSES, 728bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UPDATE_POINTERS, 729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch RELOCATE_OBJECTS 730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch }; 731bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 732bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The current stage of the collector. 733bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CollectorState state_; 734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 736bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MarkingParity marking_parity_; 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool was_marked_incrementally_; 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 740bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool evacuation_; 741109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // True if we are collecting slots to perform evacuation from evacuation 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // candidates. 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool compacting_; 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 746bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool black_allocation_; 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 748bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool have_code_to_deoptimize_; 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MarkingDeque marking_deque_; 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 752bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeFlusher* code_flusher_; 753bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 754bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch List<Page*> evacuation_candidates_; 755bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch List<Page*> newspace_evacuation_candidates_; 756bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 757bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Sweeper sweeper_; 7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Heap; 760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class StoreBuffer; 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass EvacuationScope BASE_EMBEDDED { 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit EvacuationScope(MarkCompactCollector* collector) 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : collector_(collector) { 768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier collector_->set_evacuation(true); 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~EvacuationScope() { collector_->set_evacuation(false); } 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector* collector_; 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8_EXPORT_PRIVATE const char* AllocationSpaceName(AllocationSpace space); 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_HEAP_MARK_COMPACT_H_ 782