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 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/spaces.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Callback function, returns whether an object is alive. The heap size 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// of the object is returned in size. It optionally updates the offset 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to the first live object in the page (only used for old and map objects). 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations. 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher; 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector; 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingVisitor; 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RootMarkingVisitor; 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Marking { 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Marking(Heap* heap) : heap_(heap) {} 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static MarkBit MarkBitFrom(Address addr)); 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) { 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MarkBitFrom(reinterpret_cast<Address>(obj)); 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Impossible markbits: 01 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kImpossibleBitPattern; 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsImpossible(MarkBit mark_bit)) { 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !mark_bit.Get() && mark_bit.Next().Get(); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Black markbits: 10 - this is required by the sweeper. 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kBlackBitPattern; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsBlack(MarkBit mark_bit)) { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mark_bit.Get() && !mark_bit.Next().Get(); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // White markbits: 00 - this is required by the mark bit clearer. 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kWhiteBitPattern; 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsWhite(MarkBit mark_bit)) { return !mark_bit.Get(); } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Grey markbits: 11 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kGreyBitPattern; 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsGrey(MarkBit mark_bit)) { 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mark_bit.Get() && mark_bit.Next().Get(); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void MarkBlack(MarkBit mark_bit)) { 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_bit.Set(); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_bit.Next().Clear(); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void BlackToGrey(MarkBit markbit)) { markbit.Next().Set(); } 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void WhiteToGrey(MarkBit markbit)) { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Set(); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Next().Set(); 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void GreyToBlack(MarkBit markbit)) { markbit.Next().Clear(); } 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void BlackToGrey(HeapObject* obj)) { 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlackToGrey(MarkBitFrom(obj)); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void AnyToGrey(MarkBit markbit)) { 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Set(); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Next().Set(); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TransferMark(Address old_start, Address new_start); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum ObjectColor { 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BLACK_OBJECT, 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WHITE_OBJECT, 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GREY_OBJECT, 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IMPOSSIBLE_COLOR 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* ColorName(ObjectColor color) { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (color) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case BLACK_OBJECT: 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "black"; 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case WHITE_OBJECT: 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "white"; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case GREY_OBJECT: 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "grey"; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IMPOSSIBLE_COLOR: 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "impossible"; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "error"; 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static ObjectColor Color(HeapObject* obj) { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Color(Marking::MarkBitFrom(obj)); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static ObjectColor Color(MarkBit mark_bit) { 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsBlack(mark_bit)) return BLACK_OBJECT; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsWhite(mark_bit)) return WHITE_OBJECT; 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsGrey(mark_bit)) return GREY_OBJECT; 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IMPOSSIBLE_COLOR; 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns true if the transferred color is black. 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool TransferColor(HeapObject* from, HeapObject* to)) { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit from_mark_bit = MarkBitFrom(from); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit to_mark_bit = MarkBitFrom(to); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_black = false; 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from_mark_bit.Get()) { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_mark_bit.Set(); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_black = true; // Looks black so far. 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from_mark_bit.Next().Get()) { 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_mark_bit.Next().Set(); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_black = false; // Was actually gray. 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_black; 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Marking deque for tracing live objects. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingDeque { 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingDeque() 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : array_(NULL), top_(0), bottom_(0), mask_(0), overflowed_(false) {} 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Initialize(Address low, Address high) { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_ = obj_low; 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask_ = base::bits::RoundDownToPowerOfTwo32( 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(obj_high - obj_low)) - 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1; 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = bottom_ = 0; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch overflowed_ = false; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsEmpty() { return top_ == bottom_; } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed() const { return overflowed_; } 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearOverflowed() { overflowed_ = false; } 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetOverflowed() { overflowed_ = true; } 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push the (marked) object on the marking stack if there is room, 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // otherwise mark the object as overflowed and wait for a rescan of the 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap. 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void PushBlack(HeapObject* object)) { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Marking::BlackToGrey(object); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(object->address(), -object->Size()); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[top_] = object; 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ + 1) & mask_); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void PushGrey(HeapObject* object)) { 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[top_] = object; 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ + 1) & mask_); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(HeapObject* Pop()) { 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsEmpty()); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ - 1) & mask_); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object = array_[top_]; 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void UnshiftGrey(HeapObject* object)) { 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bottom_ = ((bottom_ - 1) & mask_); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[bottom_] = object; 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array() { return array_; } 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom() { return bottom_; } 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top() { return top_; } 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask() { return mask_; } 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_top(int top) { top_ = top; } 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array_; 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // array_[(top - 1) & mask_] is the top element in the deque. The Deque is 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // empty when top_ == bottom_. It is full when top_ + 1 == bottom 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (mod mask + 1). 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top_; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom_; 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask_; 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed_; 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(MarkingDeque); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SlotsBufferAllocator { 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* AllocateBuffer(SlotsBuffer* next_buffer); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DeallocateBuffer(SlotsBuffer* buffer); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DeallocateChain(SlotsBuffer** buffer_address); 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SlotsBuffer records a sequence of slots that has to be updated 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// after live objects were relocated from evacuation candidates. 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All slots are either untyped or typed: 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Untyped slots are expected to contain a tagged object pointer. 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// They are recorded by an address. 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Typed slots are expected to contain an encoded pointer to a heap 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// object where the way of encoding depends on the type of the slot. 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// They are recorded as a pair (SlotType, slot address). 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We assume that zero-page is never mapped this allows us to distinguish 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// untyped slots from typed slots during iteration by a simple comparison: 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if element of slots buffer is less than NUMBER_OF_SLOT_TYPES then it 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is the first element of typed slot's pair. 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SlotsBuffer { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef Object** ObjectSlot; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit SlotsBuffer(SlotsBuffer* next_buffer) 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : idx_(0), chain_length_(1), next_(next_buffer) { 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_ != NULL) { 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chain_length_ = next_->chain_length_ + 1; 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~SlotsBuffer() {} 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Add(ObjectSlot slot) { 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(0 <= idx_ && idx_ < kNumberOfElements); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch slots_[idx_++] = slot; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SlotType { 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EMBEDDED_OBJECT_SLOT, 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RELOCATED_CODE_OBJECT, 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_TARGET_SLOT, 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_ENTRY_SLOT, 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEBUG_TARGET_SLOT, 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JS_RETURN_SLOT, 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NUMBER_OF_SLOT_TYPES 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* SlotTypeToString(SlotType type) { 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (type) { 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case EMBEDDED_OBJECT_SLOT: 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "EMBEDDED_OBJECT_SLOT"; 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case RELOCATED_CODE_OBJECT: 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "RELOCATED_CODE_OBJECT"; 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_TARGET_SLOT: 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "CODE_TARGET_SLOT"; 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_ENTRY_SLOT: 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "CODE_ENTRY_SLOT"; 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DEBUG_TARGET_SLOT: 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "DEBUG_TARGET_SLOT"; 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case JS_RETURN_SLOT: 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "JS_RETURN_SLOT"; 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NUMBER_OF_SLOT_TYPES: 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "NUMBER_OF_SLOT_TYPES"; 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "UNKNOWN SlotType"; 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UpdateSlots(Heap* heap); 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UpdateSlotsWithFilter(Heap* heap); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* next() { return next_; } 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int SizeOfChain(SlotsBuffer* buffer) { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer == NULL) return 0; 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<int>(buffer->idx_ + 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (buffer->chain_length_ - 1) * kNumberOfElements); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsFull() { return idx_ == kNumberOfElements; } 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; } 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer, 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool code_slots_filtering_required) { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (buffer != NULL) { 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_slots_filtering_required) { 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer->UpdateSlotsWithFilter(heap); 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer->UpdateSlots(heap); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = buffer->next(); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW }; 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool ChainLengthThresholdReached(SlotsBuffer* buffer) { 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold; 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool AddTo(SlotsBufferAllocator* allocator, 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer** buffer_address, ObjectSlot slot, 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdditionMode mode)) { 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* buffer = *buffer_address; 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer == NULL || buffer->IsFull()) { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocator->DeallocateChain(buffer_address); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = allocator->AllocateBuffer(buffer); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *buffer_address = buffer; 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer->Add(slot); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsTypedSlot(ObjectSlot slot); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool AddTo(SlotsBufferAllocator* allocator, 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer** buffer_address, SlotType type, Address addr, 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdditionMode mode); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kNumberOfElements = 1021; 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kChainLengthThreshold = 15; 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t idx_; 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t chain_length_; 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* next_; 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectSlot slots_[kNumberOfElements]; 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CodeFlusher collects candidates for code flushing during marking and 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// processes those candidates after marking has completed in order to 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// reset those functions referencing code objects that would otherwise 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be unreachable. Code objects can be referenced in three ways: 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - SharedFunctionInfo references unoptimized code. 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - JSFunction references either unoptimized or optimized code. 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - OptimizedCodeMap references optimized code. 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We are not allowed to flush unoptimized code for functions that got 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// optimized or inlined into optimized code, because we might bailout 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// into the unoptimized code again during deoptimization. 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CodeFlusher(Isolate* isolate) 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_(isolate), 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jsfunction_candidates_head_(NULL), 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_function_info_candidates_head_(NULL), 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch optimized_code_map_holder_head_(NULL) {} 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddCandidate(SharedFunctionInfo* shared_info) { 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetNextCandidate(shared_info) == NULL) { 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetNextCandidate(shared_info, shared_function_info_candidates_head_); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_function_info_candidates_head_ = shared_info; 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddCandidate(JSFunction* function) { 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function->code() == function->shared()->code()); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetNextCandidate(function)->IsUndefined()) { 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetNextCandidate(function, jsfunction_candidates_head_); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jsfunction_candidates_head_ = function; 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddOptimizedCodeMap(SharedFunctionInfo* code_map_holder) { 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetNextCodeMap(code_map_holder)->IsUndefined()) { 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetNextCodeMap(code_map_holder, optimized_code_map_holder_head_); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch optimized_code_map_holder_head_ = code_map_holder; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(SharedFunctionInfo* shared_info); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(JSFunction* function); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessCandidates() { 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessOptimizedCodeMaps(); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessSharedFunctionInfoCandidates(); 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessJSFunctionCandidates(); 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictAllCandidates() { 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvictOptimizedCodeMaps(); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvictJSFunctionCandidates(); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvictSharedFunctionInfoCandidates(); 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IteratePointersToFromSpace(ObjectVisitor* v); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessOptimizedCodeMaps(); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessJSFunctionCandidates(); 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessSharedFunctionInfoCandidates(); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictOptimizedCodeMaps(); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictJSFunctionCandidates(); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictSharedFunctionInfoCandidates(); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static JSFunction** GetNextCandidateSlot(JSFunction* candidate) { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<JSFunction**>( 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::RawField(candidate, JSFunction::kNextFunctionLinkOffset)); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static JSFunction* GetNextCandidate(JSFunction* candidate) { 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* next_candidate = candidate->next_function_link(); 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<JSFunction*>(next_candidate); 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void SetNextCandidate(JSFunction* candidate, 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* next_candidate) { 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate->set_next_function_link(next_candidate); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ClearNextCandidate(JSFunction* candidate, Object* undefined) { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(undefined->IsUndefined()); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate->set_next_function_link(undefined, SKIP_WRITE_BARRIER); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) { 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* next_candidate = candidate->code()->gc_metadata(); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<SharedFunctionInfo*>(next_candidate); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void SetNextCandidate(SharedFunctionInfo* candidate, 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* next_candidate) { 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate->code()->set_gc_metadata(next_candidate); 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ClearNextCandidate(SharedFunctionInfo* candidate) { 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER); 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static SharedFunctionInfo* GetNextCodeMap(SharedFunctionInfo* holder) { 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* next_map = code_map->get(SharedFunctionInfo::kNextMapIndex); 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<SharedFunctionInfo*>(next_map); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void SetNextCodeMap(SharedFunctionInfo* holder, 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* next_holder) { 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_map->set(SharedFunctionInfo::kNextMapIndex, next_holder); 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ClearNextCodeMap(SharedFunctionInfo* holder) { 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_map->set_undefined(SharedFunctionInfo::kNextMapIndex); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* jsfunction_candidates_head_; 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared_function_info_candidates_head_; 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* optimized_code_map_holder_head_; 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(CodeFlusher); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Defined in isolate.h. 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ThreadLocalTop; 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------------------------------------------------------------------- 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Mark-Compact collector 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector { 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the global flags, it must be called before Prepare to take effect. 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void SetFlags(int flags); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize(); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetUp(); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TearDown(); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectEvacuationCandidates(PagedSpace* space); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddEvacuationCandidate(Page* p); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prepares for GC by resetting relocation info in old and map spaces and 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // choosing spaces to compact. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Prepare(); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a global garbage collection. 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectGarbage(); 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum CompactionMode { INCREMENTAL_COMPACTION, NON_INCREMENTAL_COMPACTION }; 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool StartCompaction(CompactionMode mode); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortCompaction(); 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks whether performing mark-compact collection. 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool in_use() { return state_ > PREPARE_GC; } 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; } 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine type of object and emit deletion log event. 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate); 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distinguishable invalid map encodings (for single word and multiple words) 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that indicate free regions. 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kSingleFreeEncoding = 0; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kMultiFreeEncoding = 1; 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool IsMarked(Object* obj); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Heap* heap() const { return heap_; } 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Isolate* isolate() const; 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeFlusher* code_flusher() { return code_flusher_; } 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; } 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnableCodeFlushing(bool enable); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SweeperType { 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PARALLEL_SWEEPING, 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CONCURRENT_SWEEPING, 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SEQUENTIAL_SWEEPING 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SweepingParallelism { SWEEP_ON_MAIN_THREAD, SWEEP_IN_PARALLEL }; 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyMarkbitsAreClean(); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(PagedSpace* space); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(NewSpace* space); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyWeakEmbeddedObjectsInCode(); 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyOmittedMapChecks(); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool ShouldSkipEvacuationSlotRecording(Object** anchor)) { 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(anchor)) 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->ShouldSkipEvacuationSlotRecording(); 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(host)) 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->ShouldSkipEvacuationSlotRecording(); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsOnEvacuationCandidate(Object* obj)) { 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(obj)) 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->IsEvacuationCandidate(); 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void EvictEvacuationCandidate(Page* page)) { 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_fragmentation) { 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Page %p is too popular. Disabling evacuation.\n", 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(page)); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(gc) If all evacuation candidates are too popular we 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // should stop slots recording entirely. 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch page->ClearEvacuationCandidate(); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We were not collecting slots on this page that point 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to other evacuation candidates thus we have to 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rescan the page after evacuation to discover and update all 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pointers to evacuated objects. 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (page->owner()->identity() == OLD_DATA_SPACE) { 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch evacuation_candidates_.RemoveElement(page); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch page->SetFlag(Page::RESCAN_ON_EVACUATION); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordRelocSlot(RelocInfo* rinfo, Object* target); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordCodeEntrySlot(Address slot, Code* target); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordCodeTargetPatch(Address pc, Code* target); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void RecordSlot( 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** anchor_slot, Object** slot, Object* object, 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer::AdditionMode mode = SlotsBuffer::FAIL_ON_OVERFLOW)); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MigrateObject(HeapObject* dst, HeapObject* src, int size, 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace to_old_space); 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool TryPromoteObject(HeapObject* object, int object_size); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvalidateCode(Code* code); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearMarkbits(); 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool abort_incremental_marking() const { return abort_incremental_marking_; } 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_compacting() const { return compacting_; } 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingParity marking_parity() { return marking_parity_; } 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Concurrent and parallel sweeping support. If required_freed_bytes was set 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to a value larger than 0, then sweeping returns after a block of at least 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // required_freed_bytes was freed. If required_freed_bytes was set to zero 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // then the whole given space is swept. It returns the size of the maximum 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // continuous freed memory chunk. 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SweepInParallel(PagedSpace* space, int required_freed_bytes); 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Sweeps a given page concurrently to the sweeper threads. It returns the 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // size of the maximum continuous freed memory chunk. 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SweepInParallel(Page* page, PagedSpace* space); 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnsureSweepingCompleted(); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If sweeper threads are not active this method will return true. If 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this is a latency issue we should be smarter here. Otherwise, it will 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return true if the sweeper threads are done processing the pages. 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSweepingCompleted(); 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RefillFreeList(PagedSpace* space); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool AreSweeperThreadsActivated(); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if sweeping is in progress right now on any space. 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sweeping_in_progress() { return sweeping_in_progress_; } 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_sequential_sweeping(bool sequential_sweeping) { 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sequential_sweeping_ = sequential_sweeping; 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sequential_sweeping() const { return sequential_sweeping_; } 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the global table which maps weak objects to dependent code without 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // marking its contents. 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkWeakObjectToCodeTable(); 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for processing weak references in a full collection. We need 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to artificially keep AllocationSites alive for a time. 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkAllocationSite(AllocationSite* site); 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class SweeperTask; 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkCompactCollector(Heap* heap); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~MarkCompactCollector(); 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool MarkInvalidatedCode(); 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WillBeDeoptimized(Code* code); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RemoveDeadInvalidatedCode(); 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessInvalidatedCode(ObjectVisitor* visitor); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StartSweeperThreads(); 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum CollectorState { 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IDLE, 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PREPARE_GC, 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MARK_LIVE_OBJECTS, 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SWEEP_SPACES, 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ENCODE_FORWARDING_ADDRESSES, 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_POINTERS, 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RELOCATE_OBJECTS 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The current stage of the collector. 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectorState state_; 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool reduce_memory_footprint_; 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool abort_incremental_marking_; 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingParity marking_parity_; 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // True if we are collecting slots to perform evacuation from evacuation 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // candidates. 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool compacting_; 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool was_marked_incrementally_; 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // True if concurrent or parallel sweeping is currently in progress. 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sweeping_in_progress_; 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore pending_sweeper_jobs_semaphore_; 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sequential_sweeping_; 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBufferAllocator slots_buffer_allocator_; 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* migration_slots_buffer_; 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finishes GC, performs heap verification if enabled. 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Finish(); 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------------------------------------------- 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Phase 1: Marking live objects. 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before: The heap has been prepared for garbage collection by 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MarkCompactCollector::Prepare() and is otherwise in its 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // normal state. 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After: Live objects are marked and non-live objects are unmarked. 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class RootMarkingVisitor; 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MarkingVisitor; 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MarkCompactMarkingVisitor; 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class CodeMarkingVisitor; 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class SharedFunctionInfoMarkingVisitor; 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark code objects that are active on the stack to prevent them 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from being flushed. 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareForCodeFlushing(); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marking operations for objects reachable from roots. 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkLiveObjects(); 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AfterMarking(); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black and pushes it on the marking stack. 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black assuming that it is not yet marked. 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the heap roots and all objects reachable from them. 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkRoots(RootMarkingVisitor* visitor); 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the string table specially. References to internalized strings from 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the string table are weak. 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkStringTable(RootMarkingVisitor* visitor); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects in implicit references groups if their parent object 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is marked. 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkImplicitRefGroups(); 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessMarkingDeque(); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. This respects references only considered in 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the final atomic marking pause including the following: 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Processing of objects reachable through Harmony WeakMaps. 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Objects reachable due to host application logic like object groups 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or implicit references' groups. 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessEphemeralMarking(ObjectVisitor* visitor); 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the call-site of the top optimized code was not prepared for 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deoptimization, then treat the maps in the code as strong pointers, 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // otherwise a map can die and deoptimize the code. 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessTopOptimizedFrame(ObjectVisitor* visitor); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack. This function empties the marking stack, but may leave 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflowed objects in the heap, in which case the marking stack's 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflow flag will be set. 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmptyMarkingDeque(); 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Refill the marking stack with overflowed objects from the heap. This 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function either leaves the marking stack full or clears the overflow 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // flag on the marking stack. 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RefillMarkingDeque(); 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After reachable maps have been marked process per context object 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // literal map caches removing unmarked entries. 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessMapCaches(); 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Callback function for telling whether the object *p is an unmarked 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap object. 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsUnmarkedHeapObject(Object** p); 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsUnmarkedHeapObjectWithHeap(Heap* heap, Object** p); 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Map transitions from a live map to a dead map must be killed. 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We replace them with a null descriptor, with the same key. 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLiveReferences(); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLivePrototypeTransitions(Map* map); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLiveMapTransitions(Map* map, MarkBit map_mark); 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearMapTransitions(Map* map); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ClearMapBackPointer(Map* map); 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrimDescriptorArray(Map* map, DescriptorArray* descriptors, 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_own_descriptors); 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrimEnumCache(Map* map, DescriptorArray* descriptors); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearDependentCode(DependentCode* dependent_code); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearDependentICList(Object* head); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLiveDependentCode(DependentCode* dependent_code); 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ClearNonLiveDependentCodeInGroup(DependentCode* dependent_code, int group, 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start, int end, int new_start); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark all values associated with reachable keys in weak collections 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // encountered so far. This might push new object or even new weak maps onto 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the marking stack. 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessWeakCollections(); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After all reachable objects have been marked those weak map entries 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with an unreachable key are removed from all encountered weak maps. 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The linked list of all encountered weak maps is destroyed. 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearWeakCollections(); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to remove all encountered weak maps from the list of weak 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // collections when incremental marking is aborted. 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortWeakCollections(); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------------------------------------------- 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Phase 2: Sweeping to clear mark bits and free non-live objects for 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a non-compacting collection. 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before: Live objects are marked and non-live objects are unmarked. 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After: Live objects are unmarked, non-live regions have been added to 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // their space's free list. Active eden semispace is compacted by 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evacuation. 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we are not compacting the heap, we simply sweep the spaces except 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for the large object space, clearing mark bits and adding unmarked 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // regions to each space's free list. 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SweepSpaces(); 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int DiscoverAndEvacuateBlackObjectsOnPage(NewSpace* new_space, 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpacePage* p); 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuateNewSpace(); 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuateLiveObjectsFromPage(Page* p); 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuatePages(); 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuateNewSpaceAndCandidates(); 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ReleaseEvacuationCandidates(); 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Moves the pages of the evacuation_candidates_ list to the end of their 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // corresponding space pages list. 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MoveEvacuationCandidatesToEndOfPagesList(); 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SweepSpace(PagedSpace* space, SweeperType sweeper); 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finalizes the parallel sweeping phase. Marks all the pages that were 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // swept in parallel. 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ParallelSweepSpacesComplete(); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ParallelSweepSpaceComplete(PagedSpace* space); 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Updates store buffer and slot buffer for a pointer in a migrating object. 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordMigratedSlot(Object* value, Address slot); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MarkObjectVisitor; 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitObject(HeapObject* obj); 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class UnmarkObjectVisitor; 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void UnmarkObject(HeapObject* obj); 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingDeque marking_deque_; 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeFlusher* code_flusher_; 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool have_code_to_deoptimize_; 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<Page*> evacuation_candidates_; 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<Code*> invalidated_code_; 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmartPointer<FreeList> free_list_old_data_space_; 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmartPointer<FreeList> free_list_old_pointer_space_; 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Heap; 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkBitCellIterator BASE_EMBEDDED { 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_cell_index_ = Bitmap::IndexToCell(Bitmap::CellAlignIndex( 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(chunk_->area_end()))); 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_base_ = chunk_->area_start(); 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_index_ = Bitmap::IndexToCell( 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bitmap::CellAlignIndex(chunk_->AddressToMarkbitIndex(cell_base_))); 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cells_ = chunk_->markbits()->cells(); 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool Done() { return cell_index_ == last_cell_index_; } 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool HasNext() { return cell_index_ < last_cell_index_ - 1; } 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline MarkBit::CellType* CurrentCell() { 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &cells_[cell_index_]; 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Address CurrentCellBase() { 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cell_base_; 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Advance() { 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_index_++; 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_base_ += 32 * kPointerSize; 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* chunk_; 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit::CellType* cells_; 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int last_cell_index_; 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int cell_index_; 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address cell_base_; 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SequentialSweepingScope BASE_EMBEDDED { 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit SequentialSweepingScope(MarkCompactCollector* collector) 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : collector_(collector) { 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collector_->set_sequential_sweeping(true); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~SequentialSweepingScope() { collector_->set_sequential_sweeping(false); } 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector* collector_; 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* AllocationSpaceName(AllocationSpace space); 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8::internal 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_HEAP_MARK_COMPACT_H_ 957