mark-compact.h revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
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 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Callback function to mark an object in a given heap. 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object); 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations. 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher; 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector; 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingVisitor; 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RootMarkingVisitor; 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SlotsBuffer; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SlotsBufferAllocator; 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Marking : public AllStatic { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static MarkBit MarkBitFrom(Address addr)) { 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk* p = MemoryChunk::FromAddress(addr); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(addr)); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) { 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MarkBitFrom(reinterpret_cast<Address>(obj)); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Impossible markbits: 01 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kImpossibleBitPattern; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsImpossible(MarkBit mark_bit)) { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !mark_bit.Get() && mark_bit.Next().Get(); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Black markbits: 11 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kBlackBitPattern; 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsBlack(MarkBit mark_bit)) { 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return mark_bit.Get() && mark_bit.Next().Get(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // White markbits: 00 - this is required by the mark bit clearer. 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kWhiteBitPattern; 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static bool IsWhite(MarkBit mark_bit)) { 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsImpossible(mark_bit)); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !mark_bit.Get(); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Grey markbits: 10 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* kGreyBitPattern; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsGrey(MarkBit mark_bit)) { 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return mark_bit.Get() && !mark_bit.Next().Get(); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IsBlackOrGrey assumes that the first bit is set for black or grey 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // objects. 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static bool IsBlackOrGrey(MarkBit mark_bit)) { return mark_bit.Get(); } 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void MarkBlack(MarkBit mark_bit)) { 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_bit.Set(); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mark_bit.Next().Set(); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void MarkWhite(MarkBit mark_bit)) { 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mark_bit.Clear(); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_bit.Next().Clear(); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void BlackToWhite(MarkBit markbit)) { 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsBlack(markbit)); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Clear(); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Next().Clear(); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void GreyToWhite(MarkBit markbit)) { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsGrey(markbit)); 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Clear(); 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Next().Clear(); 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void BlackToGrey(MarkBit markbit)) { 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsBlack(markbit)); 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Next().Clear(); 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void WhiteToGrey(MarkBit markbit)) { 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsWhite(markbit)); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Set(); 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void WhiteToBlack(MarkBit markbit)) { 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsWhite(markbit)); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Set(); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Next().Set(); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void GreyToBlack(MarkBit markbit)) { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsGrey(markbit)); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Next().Set(); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void BlackToGrey(HeapObject* obj)) { 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlackToGrey(MarkBitFrom(obj)); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void AnyToGrey(MarkBit markbit)) { 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch markbit.Set(); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch markbit.Next().Clear(); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void TransferMark(Heap* heap, Address old_start, Address new_start); 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum ObjectColor { 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BLACK_OBJECT, 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WHITE_OBJECT, 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GREY_OBJECT, 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IMPOSSIBLE_COLOR 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* ColorName(ObjectColor color) { 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (color) { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case BLACK_OBJECT: 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "black"; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case WHITE_OBJECT: 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "white"; 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case GREY_OBJECT: 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "grey"; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IMPOSSIBLE_COLOR: 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "impossible"; 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "error"; 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static ObjectColor Color(HeapObject* obj) { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Color(Marking::MarkBitFrom(obj)); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static ObjectColor Color(MarkBit mark_bit) { 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsBlack(mark_bit)) return BLACK_OBJECT; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsWhite(mark_bit)) return WHITE_OBJECT; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsGrey(mark_bit)) return GREY_OBJECT; 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IMPOSSIBLE_COLOR; 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns true if the transferred color is black. 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool TransferColor(HeapObject* from, HeapObject* to)) { 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit from_mark_bit = MarkBitFrom(from); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit to_mark_bit = MarkBitFrom(to); 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Marking::IsWhite(to_mark_bit)); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from_mark_bit.Get()) { 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_mark_bit.Set(); 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (from_mark_bit.Next().Get()) { 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_mark_bit.Next().Set(); 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(Marking); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Marking deque for tracing live objects. 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkingDeque { 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingDeque() 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : array_(NULL), 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_(0), 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bottom_(0), 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mask_(0), 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch overflowed_(false), 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch in_use_(false) {} 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Initialize(Address low, Address high); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Uninitialize(bool aborting = false); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsEmpty() { return top_ == bottom_; } 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed() const { return overflowed_; } 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_use() const { return in_use_; } 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearOverflowed() { overflowed_ = false; } 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetOverflowed() { overflowed_ = true; } 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push the object on the marking stack if there is room, otherwise mark the 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // deque as overflowed and wait for a rescan of the heap. 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(bool Push(HeapObject* object)) { 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[top_] = object; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ + 1) & mask_); 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(HeapObject* Pop()) { 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsEmpty()); 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_ = ((top_ - 1) & mask_); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object = array_[top_]; 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unshift the object into the marking stack if there is room, otherwise mark 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the deque as overflowed and wait for a rescan of the heap. 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(bool Unshift(HeapObject* object)) { 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->IsHeapObject()); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFull()) { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetOverflowed(); 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bottom_ = ((bottom_ - 1) & mask_); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_[bottom_] = object; 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array() { return array_; } 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom() { return bottom_; } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top() { return top_; } 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask() { return mask_; } 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_top(int top) { top_ = top; } 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** array_; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // array_[(top - 1) & mask_] is the top element in the deque. The Deque is 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // empty when top_ == bottom_. It is full when top_ + 1 == bottom 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (mod mask + 1). 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int top_; 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bottom_; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask_; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool overflowed_; 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_use_; 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(MarkingDeque); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CodeFlusher collects candidates for code flushing during marking and 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// processes those candidates after marking has completed in order to 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// reset those functions referencing code objects that would otherwise 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// be unreachable. Code objects can be referenced in two ways: 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - SharedFunctionInfo references unoptimized code. 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - JSFunction references either unoptimized or optimized code. 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We are not allowed to flush unoptimized code for functions that got 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// optimized or inlined into optimized code, because we might bailout 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// into the unoptimized code again during deoptimization. 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeFlusher { 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CodeFlusher(Isolate* isolate) 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_(isolate), 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsfunction_candidates_head_(nullptr), 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_function_info_candidates_head_(nullptr) {} 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void AddCandidate(SharedFunctionInfo* shared_info); 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void AddCandidate(JSFunction* function); 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(SharedFunctionInfo* shared_info); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvictCandidate(JSFunction* function); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessCandidates() { 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessSharedFunctionInfoCandidates(); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessJSFunctionCandidates(); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IteratePointersToFromSpace(ObjectVisitor* v); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessJSFunctionCandidates(); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessSharedFunctionInfoCandidates(); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline JSFunction** GetNextCandidateSlot(JSFunction* candidate); 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline JSFunction* GetNextCandidate(JSFunction* candidate); 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetNextCandidate(JSFunction* candidate, 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSFunction* next_candidate); 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void ClearNextCandidate(JSFunction* candidate, 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* undefined); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline SharedFunctionInfo* GetNextCandidate( 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* candidate); 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetNextCandidate(SharedFunctionInfo* candidate, 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* next_candidate); 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void ClearNextCandidate(SharedFunctionInfo* candidate); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* jsfunction_candidates_head_; 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared_function_info_candidates_head_; 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(CodeFlusher); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Defined in isolate.h. 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ThreadLocalTop; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------------------------------------------------------------------- 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Mark-Compact collector 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkCompactCollector { 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum IterationMode { 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kKeepMarking, 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kClearMarkbits, 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize(); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetUp(); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TearDown(); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectEvacuationCandidates(PagedSpace* space); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddEvacuationCandidate(Page* p); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prepares for GC by resetting relocation info in old and map spaces and 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // choosing spaces to compact. 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Prepare(); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a global garbage collection. 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CollectGarbage(); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum CompactionMode { INCREMENTAL_COMPACTION, NON_INCREMENTAL_COMPACTION }; 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool StartCompaction(CompactionMode mode); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortCompaction(); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks whether performing mark-compact collection. 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool in_use() { return state_ > PREPARE_GC; } 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; } 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine type of object and emit deletion log event. 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate); 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distinguishable invalid map encodings (for single word and multiple words) 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that indicate free regions. 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kSingleFreeEncoding = 0; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint32_t kMultiFreeEncoding = 1; 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool IsMarked(Object* obj); 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsUnmarkedHeapObjectWithHeap(Heap* heap, Object** p); 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Heap* heap() const { return heap_; } 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Isolate* isolate() const; 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeFlusher* code_flusher() { return code_flusher_; } 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; } 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SweepingParallelism { SWEEP_ON_MAIN_THREAD, SWEEP_IN_PARALLEL }; 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VerifyValidStoreAndSlotsBufferEntries(); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyMarkbitsAreClean(); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(PagedSpace* space); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VerifyMarkbitsAreClean(NewSpace* space); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyWeakEmbeddedObjectsInCode(); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VerifyOmittedMapChecks(); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) { 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(host)) 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->ShouldSkipEvacuationSlotRecording(); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsOnEvacuationCandidate(Object* obj)) { 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Page::FromAddress(reinterpret_cast<Address>(obj)) 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->IsEvacuationCandidate(); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordRelocSlot(RelocInfo* rinfo, Object* target); 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordCodeEntrySlot(HeapObject* object, Address slot, Code* target); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordCodeTargetPatch(Address pc, Code* target); 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void RecordSlot(HeapObject* object, Object** slot, Object* target)); 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void ForceRecordSlot(HeapObject* object, Object** slot, 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* target)); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateSlots(SlotsBuffer* buffer); 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateSlotsRecordedIn(SlotsBuffer* buffer); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MigrateObject(HeapObject* dst, HeapObject* src, int size, 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllocationSpace to_old_space, 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer** evacuation_slots_buffer); 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvalidateCode(Code* code); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearMarkbits(); 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_compacting() const { return compacting_; } 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingParity marking_parity() { return marking_parity_; } 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Concurrent and parallel sweeping support. If required_freed_bytes was set 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to a value larger than 0, then sweeping returns after a block of at least 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // required_freed_bytes was freed. If required_freed_bytes was set to zero 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // then the whole given space is swept. It returns the size of the maximum 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // continuous freed memory chunk. 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SweepInParallel(PagedSpace* space, int required_freed_bytes); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Sweeps a given page concurrently to the sweeper threads. It returns the 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // size of the maximum continuous freed memory chunk. 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SweepInParallel(Page* page, PagedSpace* space); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensures that sweeping is finished. 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: Can only be called safely from main thread. 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnsureSweepingCompleted(); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SweepOrWaitUntilSweepingCompleted(Page* page); 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Help out in sweeping the corresponding space and refill memory that has 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // been regained. 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: Thread-safe. 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SweepAndRefill(CompactionSpace* space); 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If sweeper threads are not active this method will return true. If 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this is a latency issue we should be smarter here. Otherwise, it will 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return true if the sweeper threads are done processing the pages. 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSweepingCompleted(); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if sweeping is in progress right now on any space. 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sweeping_in_progress() { return sweeping_in_progress_; } 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_evacuation(bool evacuation) { evacuation_ = evacuation; } 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool evacuation() const { return evacuation_; } 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for processing weak references in a full collection. We need 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to artificially keep AllocationSites alive for a time. 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkAllocationSite(AllocationSite* site); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark objects in implicit references groups if their parent object 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // is marked. 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkImplicitRefGroups(MarkObjectFunction mark_object); 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MarkingDeque* marking_deque() { return &marking_deque_; } 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const size_t kMaxMarkingDequeSize = 4 * MB; 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const size_t kMinMarkingDequeSize = 256 * KB; 467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EnsureMarkingDequeIsCommittedAndInitialize(size_t max_size) { 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!marking_deque_.in_use()) { 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EnsureMarkingDequeIsCommitted(max_size); 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeMarkingDeque(); 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EnsureMarkingDequeIsCommitted(size_t max_size); 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EnsureMarkingDequeIsReserved(); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void InitializeMarkingDeque(); 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The following four methods can just be called after marking, when the 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // whole transitive closure is known. They must be called before sweeping 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // when mark bits are still intact. 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsSlotInBlackObjectSlow(Page* p, Address slot); 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsSlotInLiveObject(Address slot); 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Removes all the slots in the slot buffers that are within the given 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // address range. 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RemoveObjectSlots(Address start_slot, Address end_slot); 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Free lists filled by sweeper and consumed by corresponding spaces 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // (including compaction spaces). 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList>& free_list_old_space() { 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return free_list_old_space_; 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList>& free_list_code_space() { 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return free_list_code_space_; 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList>& free_list_map_space() { 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return free_list_map_space_; 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class CompactionTask; 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateNewSpaceVisitor; 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateOldSpaceVisitor; 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class EvacuateVisitorBase; 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class HeapObjectVisitor; 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class SweeperTask; 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kInitialLocalPretenuringFeedbackCapacity = 256; 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkCompactCollector(Heap* heap); 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WillBeDeoptimized(Code* code); 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvictPopularEvacuationCandidate(Page* page); 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearInvalidStoreAndSlotsBufferEntries(); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StartSweeperThreads(); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ComputeEvacuationHeuristics(int area_size, 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* target_fragmentation_percent, 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* max_evacuated_bytes); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum CollectorState { 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IDLE, 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PREPARE_GC, 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MARK_LIVE_OBJECTS, 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SWEEP_SPACES, 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ENCODE_FORWARDING_ADDRESSES, 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_POINTERS, 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RELOCATE_OBJECTS 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The current stage of the collector. 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectorState state_; 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingParity marking_parity_; 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool was_marked_incrementally_; 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool evacuation_; 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBufferAllocator* slots_buffer_allocator_; 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer* migration_slots_buffer_; 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finishes GC, performs heap verification if enabled. 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Finish(); 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------------------------------------------- 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Phase 1: Marking live objects. 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before: The heap has been prepared for garbage collection by 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MarkCompactCollector::Prepare() and is otherwise in its 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // normal state. 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After: Live objects are marked and non-live objects are unmarked. 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class CodeMarkingVisitor; 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class IncrementalMarkingMarkingVisitor; 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class MarkCompactMarkingVisitor; 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class MarkingVisitor; 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class RecordMigratedSlotVisitor; 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class RootMarkingVisitor; 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class SharedFunctionInfoMarkingVisitor; 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark code objects that are active on the stack to prevent them 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from being flushed. 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareForCodeFlushing(); 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marking operations for objects reachable from roots. 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkLiveObjects(); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Pushes a black object onto the marking stack and accounts for live bytes. 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that this assumes live bytes have not yet been counted. 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void PushBlack(HeapObject* obj)); 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unshifts a black object into the marking stack and accounts for live bytes. 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that this assumes lives bytes have already been counted. 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void UnshiftBlack(HeapObject* obj)); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black and pushes it on the marking stack. 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marks the object black assuming that it is not yet marked. 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for non-incremental marking only. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the heap roots and all objects reachable from them. 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkRoots(RootMarkingVisitor* visitor); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the string table specially. References to internalized strings from 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the string table are weak. 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkStringTable(RootMarkingVisitor* visitor); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessMarkingDeque(); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking stack 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or overflowed in the heap. This respects references only considered in 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the final atomic marking pause including the following: 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Processing of objects reachable through Harmony WeakMaps. 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Objects reachable due to host application logic like object groups 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or implicit references' groups. 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ProcessEphemeralMarking(ObjectVisitor* visitor, 616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool only_process_harmony_weak_collections); 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the call-site of the top optimized code was not prepared for 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deoptimization, then treat the maps in the code as strong pointers, 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // otherwise a map can die and deoptimize the code. 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessTopOptimizedFrame(ObjectVisitor* visitor); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Collects a list of dependent code from maps embedded in optimize code. 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode* DependentCodeListFromNonLiveMaps(); 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark objects reachable (transitively) from objects in the marking 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack. This function empties the marking stack, but may leave 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflowed objects in the heap, in which case the marking stack's 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // overflow flag will be set. 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmptyMarkingDeque(); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Refill the marking stack with overflowed objects from the heap. This 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function either leaves the marking stack full or clears the overflow 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // flag on the marking stack. 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RefillMarkingDeque(); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Helper methods for refilling the marking stack by discovering grey objects 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // on various pages of the heap. Used by {RefillMarkingDeque} only. 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class T> 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsWithIterator(T* it); 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsOnPage(MemoryChunk* p); 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsInSpace(PagedSpace* space); 643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DiscoverGreyObjectsInNewSpace(); 644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Callback function for telling whether the object *p is an unmarked 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap object. 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsUnmarkedHeapObject(Object** p); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear non-live references in weak cells, transition and descriptor arrays, 650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and deoptimize dependent code of non-live maps. 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearNonLiveReferences(); 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkDependentCodeForDeoptimization(DependentCode* list); 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find non-live targets of simple transitions in the given list. Clear 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // transitions to non-live targets and if needed trim descriptors arrays. 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearSimpleMapTransitions(Object* non_live_map_list); 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearSimpleMapTransition(Map* map, Map* dead_transition); 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compact every array in the global list of transition arrays and 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // trim the corresponding descriptor array if a transition target is non-live. 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearFullMapTransitions(); 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CompactTransitionArray(Map* map, TransitionArray* transitions, 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DescriptorArray* descriptors); 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TrimDescriptorArray(Map* map, DescriptorArray* descriptors); 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrimEnumCache(Map* map, DescriptorArray* descriptors); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark all values associated with reachable keys in weak collections 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // encountered so far. This might push new object or even new weak maps onto 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the marking stack. 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProcessWeakCollections(); 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After all reachable objects have been marked those weak map entries 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with an unreachable key are removed from all encountered weak maps. 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The linked list of all encountered weak maps is destroyed. 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearWeakCollections(); 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to remove all encountered weak maps from the list of weak 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // collections when incremental marking is aborted. 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AbortWeakCollections(); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearWeakCells(Object** non_live_map_list, 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode** dependent_code_list); 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AbortWeakCells(); 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AbortTransitionArrays(); 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------------------------------------------- 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Phase 2: Sweeping to clear mark bits and free non-live objects for 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a non-compacting collection. 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before: Live objects are marked and non-live objects are unmarked. 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After: Live objects are unmarked, non-live regions have been added to 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // their space's free list. Active eden semispace is compacted by 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evacuation. 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we are not compacting the heap, we simply sweep the spaces except 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for the large object space, clearing mark bits and adding unmarked 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // regions to each space's free list. 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SweepSpaces(); 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvacuateNewSpacePrologue(); 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns local pretenuring feedback. 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HashMap* EvacuateNewSpaceInParallel(); 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AddEvacuationSlotsBufferSynchronized( 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer* evacuation_slots_buffer); 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvacuatePages(CompactionSpaceCollection* compaction_spaces, 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer** evacuation_slots_buffer); 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EvacuatePagesInParallel(); 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The number of parallel compaction tasks, including the main thread. 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int NumberOfParallelCompactionTasks(); 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void StartParallelCompaction(CompactionSpaceCollection** compaction_spaces, 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t* task_ids, int len); 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void WaitUntilCompactionCompleted(uint32_t* task_ids, int len); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EvacuateNewSpaceAndCandidates(); 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdatePointersAfterEvacuation(); 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Iterates through all live objects on a page using marking information. 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns whether all objects have successfully been visited. 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool VisitLiveObjects(MemoryChunk* page, HeapObjectVisitor* visitor, 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IterationMode mode); 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VisitLiveObjectsBody(Page* page, ObjectVisitor* visitor); 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecomputeLiveBytes(MemoryChunk* page); 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SweepAbortedPages(); 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ReleaseEvacuationCandidates(); 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Moves the pages of the evacuation_candidates_ list to the end of their 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // corresponding space pages list. 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MoveEvacuationCandidatesToEndOfPagesList(); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Starts sweeping of a space by contributing on the main thread and setting 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // up other pages for sweeping. 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void StartSweepSpace(PagedSpace* space); 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finalizes the parallel sweeping phase. Marks all the pages that were 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // swept in parallel. 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ParallelSweepSpacesComplete(); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ParallelSweepSpaceComplete(PagedSpace* space); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Updates store buffer and slot buffer for a pointer in a migrating object. 754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordMigratedSlot(Object* value, Address slot, 755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer** evacuation_slots_buffer); 756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Adds the code entry slot to the slots buffer. 758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordMigratedCodeEntrySlot(Address code_entry, Address code_entry_slot, 759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer** evacuation_slots_buffer); 760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Adds the slot of a moved code object. 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordMigratedCodeObjectSlot(Address code_object, 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlotsBuffer** evacuation_slots_buffer); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MarkObjectVisitor; 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitObject(HeapObject* obj); 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class UnmarkObjectVisitor; 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void UnmarkObject(HeapObject* obj); 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::VirtualMemory* marking_deque_memory_; 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t marking_deque_memory_committed_; 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingDeque marking_deque_; 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeFlusher* code_flusher_; 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool have_code_to_deoptimize_; 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<Page*> evacuation_candidates_; 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch List<MemoryChunk*> newspace_evacuation_candidates_; 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The evacuation_slots_buffers_ are used by the compaction threads. 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // When a compaction task finishes, it uses 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // AddEvacuationSlotsbufferSynchronized to adds its slots buffer to the 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // evacuation_slots_buffers_ list using the evacuation_slots_buffers_mutex_ 788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // lock. 789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::Mutex evacuation_slots_buffers_mutex_; 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch List<SlotsBuffer*> evacuation_slots_buffers_; 791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList> free_list_old_space_; 793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList> free_list_code_space_; 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::SmartPointer<FreeList> free_list_map_space_; 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // True if we are collecting slots to perform evacuation from evacuation 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // candidates. 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool compacting_; 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // True if concurrent or parallel sweeping is currently in progress. 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool sweeping_in_progress_; 802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // True if parallel compaction is currently in progress. 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool compaction_in_progress_; 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Semaphore used to synchronize sweeper tasks. 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::Semaphore pending_sweeper_tasks_semaphore_; 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Semaphore used to synchronize compaction tasks. 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::Semaphore pending_compaction_tasks_semaphore_; 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Heap; 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class StoreBuffer; 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MarkBitCellIterator BASE_EMBEDDED { 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_cell_index_ = Bitmap::IndexToCell(Bitmap::CellAlignIndex( 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(chunk_->area_end()))); 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_base_ = chunk_->area_start(); 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_index_ = Bitmap::IndexToCell( 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bitmap::CellAlignIndex(chunk_->AddressToMarkbitIndex(cell_base_))); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cells_ = chunk_->markbits()->cells(); 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool Done() { return cell_index_ == last_cell_index_; } 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool HasNext() { return cell_index_ < last_cell_index_ - 1; } 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline MarkBit::CellType* CurrentCell() { 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &cells_[cell_index_]; 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Address CurrentCellBase() { 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cell_index_ == Bitmap::IndexToCell(Bitmap::CellAlignIndex( 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_->AddressToMarkbitIndex(cell_base_)))); 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cell_base_; 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Advance() { 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_index_++; 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_base_ += 32 * kPointerSize; 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Return the next mark bit cell. If there is no next it returns 0; 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline MarkBit::CellType PeekNext() { 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasNext()) { 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return cells_[cell_index_ + 1]; 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* chunk_; 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit::CellType* cells_; 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int last_cell_index_; 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int cell_index_; 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address cell_base_; 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum LiveObjectIterationMode { kBlackObjects, kGreyObjects, kAllLiveObjects }; 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <LiveObjectIterationMode T> 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LiveObjectIterator BASE_EMBEDDED { 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit LiveObjectIterator(MemoryChunk* chunk) 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : chunk_(chunk), 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it_(chunk_), 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cell_base_(it_.CurrentCellBase()), 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_cell_(*it_.CurrentCell()) {} 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObject* Next(); 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk* chunk_; 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MarkBitCellIterator it_; 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address cell_base_; 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MarkBit::CellType current_cell_; 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass EvacuationScope BASE_EMBEDDED { 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit EvacuationScope(MarkCompactCollector* collector) 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : collector_(collector) { 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier collector_->set_evacuation(true); 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~EvacuationScope() { collector_->set_evacuation(false); } 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector* collector_; 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* AllocationSpaceName(AllocationSpace space); 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_HEAP_MARK_COMPACT_H_ 905