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_OBJECTS_VISITING_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_OBJECTS_VISITING_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This file provides base classes and auxiliary methods for defining 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// static object visitors used during GC. 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Visiting HeapObject body with a normal ObjectVisitor requires performing 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// two switches on object's instance type to determine object size and layout 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and one or more virtual method calls on visitor itself. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Static visitor is different: it provides a dispatch table which contains 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// pointers to specialized visit functions. Each map has the visitor_id 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// field which contains an index of specialized visitor to use. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Base class for all static visitors. 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StaticVisitorBase : public AllStatic { 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define VISITOR_ID_LIST(V) \ 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(SeqOneByteString) \ 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(SeqTwoByteString) \ 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ShortcutCandidate) \ 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ByteArray) \ 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(FreeSpace) \ 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(FixedArray) \ 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(FixedDoubleArray) \ 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(FixedTypedArray) \ 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(FixedFloat64Array) \ 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ConstantPoolArray) \ 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(NativeContext) \ 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(AllocationSite) \ 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject2) \ 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject3) \ 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject4) \ 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject5) \ 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject6) \ 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject7) \ 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject8) \ 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObject9) \ 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DataObjectGeneric) \ 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject2) \ 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject3) \ 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject4) \ 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject5) \ 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject6) \ 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject7) \ 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject8) \ 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObject9) \ 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSObjectGeneric) \ 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct2) \ 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct3) \ 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct4) \ 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct5) \ 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct6) \ 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct7) \ 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct8) \ 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Struct9) \ 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(StructGeneric) \ 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ConsString) \ 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(SlicedString) \ 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Symbol) \ 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Oddball) \ 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Code) \ 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Map) \ 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Cell) \ 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(PropertyCell) \ 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(SharedFunctionInfo) \ 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSFunction) \ 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSWeakCollection) \ 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSArrayBuffer) \ 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSTypedArray) \ 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSDataView) \ 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(JSRegExp) 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For data objects, JS objects and structs along with generic visitor which 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can visit object of any size we provide visitors specialized by 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object size in words. 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ids of specialized visitors are declared in a linear order (without 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // holes) starting from the id of visitor specialized for 2 words objects 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (base visitor id) and ending with the id of generic visitor. 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Method GetVisitorIdForSize depends on this ordering to calculate visitor 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // id of specialized visitor from given instance size, base visitor id and 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generic visitor's id. 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum VisitorId { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define VISITOR_ID_ENUM_DECL(id) kVisit##id, 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef VISITOR_ID_ENUM_DECL 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitorIdCount, 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitDataObject = kVisitDataObject2, 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitJSObject = kVisitJSObject2, 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitStruct = kVisitStruct2, 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMinObjectSizeInWords = 2 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visitor ID should fit in one byte. 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kVisitorIdCount <= 256); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine which specialized visitor should be used for given instance type 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and instance type. 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorId GetVisitorId(int instance_type, int instance_size); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorId GetVisitorId(Map* map) { 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetVisitorId(map->instance_type(), map->instance_size()); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For visitors that allow specialization by size calculate VisitorId based 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on size, base visitor id and generic visitor id. 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic, 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size) { 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((base == kVisitDataObject) || (base == kVisitStruct) || 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (base == kVisitJSObject)); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(object_size, kPointerSize)); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const VisitorId specialization = static_cast<VisitorId>( 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Min(specialization, generic); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Callback> 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VisitorDispatchTable { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CopyFrom(VisitorDispatchTable* other) { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are not using memcpy to guarantee that during update 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // every element of callbacks_ array will remain correct 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pointer (memcpy might be implemented as a byte copying loop). 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) { 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) { 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Callback>(callbacks_[id]); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Callback GetVisitor(Map* map) { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Callback>(callbacks_[map->visitor_id()]); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Register(StaticVisitorBase::VisitorId id, Callback callback) { 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <typename Visitor, StaticVisitorBase::VisitorId base, 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::VisitorId generic, int object_size_in_words> 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RegisterSpecialization() { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int size = object_size_in_words * kPointerSize; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size), 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &Visitor::template VisitSpecialized<size>); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <typename Visitor, StaticVisitorBase::VisitorId base, 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::VisitorId generic> 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RegisterSpecializations() { 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT((generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10); 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 2>(); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 3>(); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 4>(); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 5>(); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 6>(); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 7>(); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 8>(); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterSpecialization<Visitor, base, generic, 9>(); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register(generic, &Visitor::Visit); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor> 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BodyVisitorBase : public AllStatic { 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void IteratePointers(Heap* heap, HeapObject* object, 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_offset, int end_offset)) { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** start_slot = 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Object**>(object->address() + start_offset); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** end_slot = 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Object**>(object->address() + end_offset); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitPointers(heap, start_slot, end_slot); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = BodyDescriptor::SizeOf(map, object); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BodyVisitorBase<StaticVisitor>::IteratePointers( 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<ReturnType>(object_size); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <int object_size> 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BodyVisitorBase<StaticVisitor>::IteratePointers( 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<ReturnType>(object_size); 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BodyVisitorBase<StaticVisitor>::IteratePointers( 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->GetHeap(), object, BodyDescriptor::kStartOffset, 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BodyDescriptor::kEndOffset); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<ReturnType>(BodyDescriptor::kSize); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Base class for visitors used for a linear new space iteration. 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IterateBody returns size of visited object. 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Certain types of objects (i.e. Code objects) are not handled 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// by dispatch table of this visitor because they cannot appear 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in the new space. 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This class is intended to be used in the following way: 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// class SomeVisitor : public StaticNewSpaceVisitor<SomeVisitor> { 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ... 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This is an example of Curiously recurring template pattern 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We use CRTP to guarantee aggressive compile time optimizations (i.e. 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// inlining and specialization of StaticVisitor::VisitPointers methods). 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor> 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StaticNewSpaceVisitor : public StaticVisitorBase { 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize(); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int IterateBody(Map* map, HeapObject* obj)) { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return table_.GetVisitor(map)(map, obj); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) StaticVisitor::VisitPointer(heap, p); 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitJSFunction(Map* map, HeapObject* object)) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = map->GetHeap(); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitPointers(heap, 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::RawField(object, JSFunction::kPropertiesOffset), 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::RawField(object, JSFunction::kCodeEntryOffset)); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't visit code entry. We are using this visitor only during scavenges. 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitPointers( 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap, HeapObject::RawField(object, 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction::kCodeEntryOffset + kPointerSize), 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset)); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return JSFunction::kSize; 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitByteArray(Map* map, HeapObject* object)) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<ByteArray*>(object)->ByteArraySize(); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FixedDoubleArray::SizeFor(length); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitFixedTypedArray(Map* map, HeapObject* object)) { 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<FixedTypedArrayBase*>(object)->size(); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitJSObject(Map* map, HeapObject* object)) { 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return JSObjectVisitor::Visit(map, object); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) { 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SeqOneByteString::cast(object) 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->SeqOneByteStringSize(map->instance_type()); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SeqTwoByteString::cast(object) 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->SeqTwoByteStringSize(map->instance_type()); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitFreeSpace(Map* map, HeapObject* object)) { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FreeSpace::cast(object)->Size(); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitJSArrayBuffer(Map* map, HeapObject* object)); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitJSTypedArray(Map* map, HeapObject* object)); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int VisitJSDataView(Map* map, HeapObject* object)); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class DataObjectVisitor { 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <int object_size> 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline int VisitSpecialized(Map* map, HeapObject* object) { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object_size; 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static int Visit(Map* map, HeapObject* object)) { 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return map->instance_size(); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int> 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StructVisitor; 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int> 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObjectVisitor; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef int (*Callback)(Map* map, HeapObject* object); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorDispatchTable<Callback> table_; 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor> 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback> 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticNewSpaceVisitor<StaticVisitor>::table_; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Base class for visitors used to transitively mark the entire heap. 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IterateBody returns nothing. 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Certain types of objects might not be handled by this base class and 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// no visitor function is registered by the generic initialization. A 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specialized visitor function needs to be provided by the inheriting 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// class itself for those cases. 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This class is intended to be used in the following way: 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> { 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ... 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This is an example of Curiously recurring template pattern. 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor> 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StaticMarkingVisitor : public StaticVisitorBase { 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize(); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void IterateBody(Map* map, HeapObject* obj)) { 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.GetVisitor(map)(map, obj); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitPropertyCell(Map* map, HeapObject* object)); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address)); 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo)); 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo)); 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo)); 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo)); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo)); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitExternalReference(RelocInfo* rinfo)) {} 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitRuntimeEntry(RelocInfo* rinfo)) {} 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip the weak next code link in a code object. 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitNextCodeLink(Heap* heap, Object** slot)) {} 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mstarzinger): This should be made protected once refactoring is done. 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark non-optimize code for functions inlined into the given optimized 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code. This will prevent it from being flushed. 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MarkInlinedFunctionsCode(Heap* heap, Code* code); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitMap(Map* map, HeapObject* object)); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitCode(Map* map, HeapObject* object)); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object)); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitConstantPoolArray(Map* map, HeapObject* object)); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitAllocationSite(Map* map, HeapObject* object)); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitWeakCollection(Map* map, HeapObject* object)); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitJSFunction(Map* map, HeapObject* object)); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitJSRegExp(Map* map, HeapObject* object)); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitJSArrayBuffer(Map* map, HeapObject* object)); 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitJSTypedArray(Map* map, HeapObject* object)); 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitJSDataView(Map* map, HeapObject* object)); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void VisitNativeContext(Map* map, HeapObject* object)); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark pointers in a Map and its TransitionArray together, possibly 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // treating transitions or back pointers weak. 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MarkMapContents(Heap* heap, Map* map); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MarkTransitionArray(Heap* heap, TransitionArray* transitions); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code flushing support. 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsFlushable(Heap* heap, JSFunction* function)); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info)); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helpers used by code flushing support that visit pointer fields and treat 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // references to code objects either strongly or weakly. 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitSharedFunctionInfoStrongCode(Heap* heap, HeapObject* object); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitSharedFunctionInfoWeakCode(Heap* heap, HeapObject* object); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitJSFunctionStrongCode(Heap* heap, HeapObject* object); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void VisitJSFunctionWeakCode(Heap* heap, HeapObject* object); 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class DataObjectVisitor { 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <int size> 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void VisitSpecialized(Map* map, HeapObject* object) {} 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void Visit(Map* map, HeapObject* object)) {} 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void> 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayVisitor; 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void> 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObjectVisitor; 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, void> 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StructObjectVisitor; 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef void (*Callback)(Map* map, HeapObject* object); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorDispatchTable<Callback> table_; 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename StaticVisitor> 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback> 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticMarkingVisitor<StaticVisitor>::table_; 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass WeakObjectRetainer; 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A weak list is single linked list where each element has a weak pointer to 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the next element. Given the head of the list, this function removes dead 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// elements from the list and if requested records slots for next-element 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// pointers. The template parameter T is a WeakListVisitor that defines how to 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// access the next-element pointers. 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class T> 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8::internal 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_OBJECTS_VISITING_H_ 453