1b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
5eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org#ifndef V8_OBJECTS_VISITING_H_
6eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org#define V8_OBJECTS_VISITING_H_
7ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
91c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
10ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// This file provides base classes and auxiliary methods for defining
11ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// static object visitors used during GC.
12ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Visiting HeapObject body with a normal ObjectVisitor requires performing
13ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// two switches on object's instance type to determine object size and layout
14ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// and one or more virtual method calls on visitor itself.
15ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Static visitor is different: it provides a dispatch table which contains
16ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// pointers to specialized visit functions. Each map has the visitor_id
17ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// field which contains an index of specialized visitor to use.
18ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
19ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgnamespace v8 {
20ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgnamespace internal {
21ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
22ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
23ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Base class for all static visitors.
24ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass StaticVisitorBase : public AllStatic {
25ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#define VISITOR_ID_LIST(V) \
278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(SeqOneByteString)      \
288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(SeqTwoByteString)      \
298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(ShortcutCandidate)     \
308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(ByteArray)             \
318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(FreeSpace)             \
328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(FixedArray)            \
338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(FixedDoubleArray)      \
348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(FixedTypedArray)       \
358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(FixedFloat64Array)     \
368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(ConstantPoolArray)     \
378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(NativeContext)         \
388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(AllocationSite)        \
398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject2)           \
408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject3)           \
418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject4)           \
428640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject5)           \
438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject6)           \
448640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject7)           \
458640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject8)           \
468640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObject9)           \
478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(DataObjectGeneric)     \
488640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject2)             \
498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject3)             \
508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject4)             \
518640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject5)             \
528640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject6)             \
538640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject7)             \
548640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject8)             \
558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObject9)             \
568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSObjectGeneric)       \
578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct2)               \
588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct3)               \
598640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct4)               \
608640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct5)               \
618640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct6)               \
628640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct7)               \
638640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct8)               \
648640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Struct9)               \
658640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(StructGeneric)         \
668640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(ConsString)            \
678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(SlicedString)          \
688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Symbol)                \
698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Oddball)               \
708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Code)                  \
718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Map)                   \
728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(Cell)                  \
738640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(PropertyCell)          \
748640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(SharedFunctionInfo)    \
758640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSFunction)            \
768640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSWeakCollection)      \
778640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSArrayBuffer)         \
788640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSTypedArray)          \
798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  V(JSDataView)            \
8028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  V(JSRegExp)
8128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
8228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // For data objects, JS objects and structs along with generic visitor which
8328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // can visit object of any size we provide visitors specialized by
8428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // object size in words.
8528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // Ids of specialized visitors are declared in a linear order (without
8628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // holes) starting from the id of visitor specialized for 2 words objects
8728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // (base visitor id) and ending with the id of generic visitor.
8828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // Method GetVisitorIdForSize depends on this ordering to calculate visitor
8928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // id of specialized visitor from given instance size, base visitor id and
9028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // generic visitor's id.
91ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  enum VisitorId {
928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
9328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
9428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#undef VISITOR_ID_ENUM_DECL
95ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    kVisitorIdCount,
9628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    kVisitDataObject = kVisitDataObject2,
9728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    kVisitJSObject = kVisitJSObject2,
9828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    kVisitStruct = kVisitStruct2,
99ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    kMinObjectSizeInWords = 2
100ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  };
101ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1025b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Visitor ID should fit in one byte.
1035b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  STATIC_ASSERT(kVisitorIdCount <= 256);
1045b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
105ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // Determine which specialized visitor should be used for given instance type
106ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // and instance type.
107ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static VisitorId GetVisitorId(int instance_type, int instance_size);
108ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
109ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static VisitorId GetVisitorId(Map* map) {
110ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return GetVisitorId(map->instance_type(), map->instance_size());
111ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
112ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
113ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // For visitors that allow specialization by size calculate VisitorId based
114ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // on size, base visitor id and generic visitor id.
1158640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
116ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                       int object_size) {
1178640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    DCHECK((base == kVisitDataObject) || (base == kVisitStruct) ||
118ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org           (base == kVisitJSObject));
119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsAligned(object_size, kPointerSize));
120e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size);
121e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
122ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
123ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    const VisitorId specialization = static_cast<VisitorId>(
124ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords);
125ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
126ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return Min(specialization, generic);
127ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
128ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
129ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
130ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename Callback>
132ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass VisitorDispatchTable {
133ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
134c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  void CopyFrom(VisitorDispatchTable* other) {
135c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    // We are not using memcpy to guarantee that during update
136c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    // every element of callbacks_ array will remain correct
137c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    // pointer (memcpy might be implemented as a byte copying loop).
138c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) {
1391e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]);
140c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
141c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
142c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
143a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) {
144a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    return reinterpret_cast<Callback>(callbacks_[id]);
145a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
146a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
147ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  inline Callback GetVisitor(Map* map) {
148c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return reinterpret_cast<Callback>(callbacks_[map->visitor_id()]);
149ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
150ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
151ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  void Register(StaticVisitorBase::VisitorId id, Callback callback) {
152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(id < StaticVisitorBase::kVisitorIdCount);  // id is unsigned.
1531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
154ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
155ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  template <typename Visitor, StaticVisitorBase::VisitorId base,
1578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org            StaticVisitorBase::VisitorId generic, int object_size_in_words>
158ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  void RegisterSpecialization() {
159ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    static const int size = object_size_in_words * kPointerSize;
160ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size),
161ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org             &Visitor::template VisitSpecialized<size>);
162ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
163ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
164ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1658640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  template <typename Visitor, StaticVisitorBase::VisitorId base,
1668640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org            StaticVisitorBase::VisitorId generic>
167ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  void RegisterSpecializations() {
1688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    STATIC_ASSERT((generic - base + StaticVisitorBase::kMinObjectSizeInWords) ==
1698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org                  10);
170ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 2>();
171ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 3>();
172ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 4>();
173ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 5>();
174ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 6>();
175ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 7>();
176ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 8>();
177ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    RegisterSpecialization<Visitor, base, generic, 9>();
178ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Register(generic, &Visitor::Visit);
179ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
180ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
181ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org private:
1821e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount];
183ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
184ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
185ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1868640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor>
187ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass BodyVisitorBase : public AllStatic {
188ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
1898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  INLINE(static void IteratePointers(Heap* heap, HeapObject* object,
1908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org                                     int start_offset, int end_offset)) {
1918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    Object** start_slot =
1928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        reinterpret_cast<Object**>(object->address() + start_offset);
1938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    Object** end_slot =
1948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        reinterpret_cast<Object**>(object->address() + end_offset);
1952ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    StaticVisitor::VisitPointers(heap, start_slot, end_slot);
196ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
197ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
198ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
199ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2008640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
201ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> {
202ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
203003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
204ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = BodyDescriptor::SizeOf(map, object);
205145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com    BodyVisitorBase<StaticVisitor>::IteratePointers(
2068640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
207ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return static_cast<ReturnType>(object_size);
208ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
209ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2108640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  template <int object_size>
211ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(BodyDescriptor::SizeOf(map, object) == object_size);
213145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com    BodyVisitorBase<StaticVisitor>::IteratePointers(
2148640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
215ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return static_cast<ReturnType>(object_size);
216ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
217ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
218ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
219ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
221ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> {
222ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
223003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
224145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com    BodyVisitorBase<StaticVisitor>::IteratePointers(
2258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        map->GetHeap(), object, BodyDescriptor::kStartOffset,
226ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        BodyDescriptor::kEndOffset);
227ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return static_cast<ReturnType>(BodyDescriptor::kSize);
228ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
229ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
230ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
231ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
232ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Base class for visitors used for a linear new space iteration.
233ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// IterateBody returns size of visited object.
234ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Certain types of objects (i.e. Code objects) are not handled
235ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// by dispatch table of this visitor because they cannot appear
236ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// in the new space.
237ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//
238ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// This class is intended to be used in the following way:
239ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//
240ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//   class SomeVisitor : public StaticNewSpaceVisitor<SomeVisitor> {
241ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//     ...
242ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//   }
243ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org//
244ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// This is an example of Curiously recurring template pattern
245ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
246ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// We use CRTP to guarantee aggressive compile time optimizations (i.e.
247ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// inlining and specialization of StaticVisitor::VisitPointers methods).
2488640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor>
249ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass StaticNewSpaceVisitor : public StaticVisitorBase {
250ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static void Initialize();
252ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
253003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int IterateBody(Map* map, HeapObject* obj)) {
254ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return table_.GetVisitor(map)(map, obj);
255ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
256ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
257003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
258ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    for (Object** p = start; p < end; p++) StaticVisitor::VisitPointer(heap, p);
259ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
260ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
261ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org private:
262003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitJSFunction(Map* map, HeapObject* object)) {
263ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    Heap* heap = map->GetHeap();
264ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    VisitPointers(heap,
2652ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org                  HeapObject::RawField(object, JSFunction::kPropertiesOffset),
266ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                  HeapObject::RawField(object, JSFunction::kCodeEntryOffset));
267ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
268ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // Don't visit code entry. We are using this visitor only during scavenges.
269ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
270ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    VisitPointers(
2718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        heap, HeapObject::RawField(object,
2728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org                                   JSFunction::kCodeEntryOffset + kPointerSize),
2738640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset));
274ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return JSFunction::kSize;
275ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
276ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
277003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitByteArray(Map* map, HeapObject* object)) {
278ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return reinterpret_cast<ByteArray*>(object)->ByteArraySize();
279ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
280ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
281003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) {
2826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
2836d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    return FixedDoubleArray::SizeFor(length);
2846d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
2856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
2865c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  INLINE(static int VisitFixedTypedArray(Map* map, HeapObject* object)) {
2875c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    return reinterpret_cast<FixedTypedArrayBase*>(object)->size();
2885c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
2895c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
290003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitJSObject(Map* map, HeapObject* object)) {
2917c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    return JSObjectVisitor::Visit(map, object);
2927c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  }
2937c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
294003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) {
2958640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    return SeqOneByteString::cast(object)
2968640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        ->SeqOneByteStringSize(map->instance_type());
297ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
298ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
299003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) {
3008640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    return SeqTwoByteString::cast(object)
3018640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        ->SeqTwoByteStringSize(map->instance_type());
302ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
303ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
304003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static int VisitFreeSpace(Map* map, HeapObject* object)) {
305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return FreeSpace::cast(object)->Size();
306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  INLINE(static int VisitJSArrayBuffer(Map* map, HeapObject* object));
3091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  INLINE(static int VisitJSTypedArray(Map* map, HeapObject* object));
3101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  INLINE(static int VisitJSDataView(Map* map, HeapObject* object));
3111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
312ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  class DataObjectVisitor {
313ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org   public:
3148640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    template <int object_size>
315ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    static inline int VisitSpecialized(Map* map, HeapObject* object) {
316ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      return object_size;
317ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
318ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
319003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    INLINE(static int Visit(Map* map, HeapObject* object)) {
320ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      return map->instance_size();
321ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
322ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  };
323ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int>
3258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      StructVisitor;
326ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int>
3288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      JSObjectVisitor;
329ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
330ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  typedef int (*Callback)(Map* map, HeapObject* object);
331ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
332ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static VisitorDispatchTable<Callback> table_;
333ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
334ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
335ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor>
337ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgVisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
338b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    StaticNewSpaceVisitor<StaticVisitor>::table_;
339b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
340b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
341b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Base class for visitors used to transitively mark the entire heap.
342b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// IterateBody returns nothing.
343b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Certain types of objects might not be handled by this base class and
344b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// no visitor function is registered by the generic initialization. A
345b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// specialized visitor function needs to be provided by the inheriting
346b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// class itself for those cases.
347b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//
348b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// This class is intended to be used in the following way:
349b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//
350b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//   class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> {
351b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//     ...
352b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//   }
353b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org//
354b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// This is an example of Curiously recurring template pattern.
3558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor>
356b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass StaticMarkingVisitor : public StaticVisitorBase {
357b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org public:
358b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  static void Initialize();
359b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
360003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void IterateBody(Map* map, HeapObject* obj)) {
361b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    table_.GetVisitor(map)(map, obj);
362b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  }
363b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
3641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  INLINE(static void VisitPropertyCell(Map* map, HeapObject* object));
365003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address));
366003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo));
36741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo));
368003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo));
369003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo));
370003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo));
3718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  INLINE(static void VisitExternalReference(RelocInfo* rinfo)) {}
3728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  INLINE(static void VisitRuntimeEntry(RelocInfo* rinfo)) {}
373895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // Skip the weak next code link in a code object.
3748640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  INLINE(static void VisitNextCodeLink(Heap* heap, Object** slot)) {}
375b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
376b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  // TODO(mstarzinger): This should be made protected once refactoring is done.
377c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Mark non-optimize code for functions inlined into the given optimized
378c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // code. This will prevent it from being flushed.
379c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  static void MarkInlinedFunctionsCode(Heap* heap, Code* code);
380c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
381b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org protected:
382003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitMap(Map* map, HeapObject* object));
383003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitCode(Map* map, HeapObject* object));
384003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object));
385a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  INLINE(static void VisitConstantPoolArray(Map* map, HeapObject* object));
386e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  INLINE(static void VisitAllocationSite(Map* map, HeapObject* object));
387e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  INLINE(static void VisitWeakCollection(Map* map, HeapObject* object));
388003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitJSFunction(Map* map, HeapObject* object));
389003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitJSRegExp(Map* map, HeapObject* object));
3901fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  INLINE(static void VisitJSArrayBuffer(Map* map, HeapObject* object));
3911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  INLINE(static void VisitJSTypedArray(Map* map, HeapObject* object));
3921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  INLINE(static void VisitJSDataView(Map* map, HeapObject* object));
393003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static void VisitNativeContext(Map* map, HeapObject* object));
394b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
39533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  // Mark pointers in a Map and its TransitionArray together, possibly
39633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  // treating transitions or back pointers weak.
39733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  static void MarkMapContents(Heap* heap, Map* map);
39833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  static void MarkTransitionArray(Heap* heap, TransitionArray* transitions);
39933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
400c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Code flushing support.
401003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static bool IsFlushable(Heap* heap, JSFunction* function));
402003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info));
403c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
404c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Helpers used by code flushing support that visit pointer fields and treat
405c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // references to code objects either strongly or weakly.
406c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  static void VisitSharedFunctionInfoStrongCode(Heap* heap, HeapObject* object);
407c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  static void VisitSharedFunctionInfoWeakCode(Heap* heap, HeapObject* object);
408c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  static void VisitJSFunctionStrongCode(Heap* heap, HeapObject* object);
409c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  static void VisitJSFunctionWeakCode(Heap* heap, HeapObject* object);
410c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
411b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  class DataObjectVisitor {
412b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org   public:
4138640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    template <int size>
4148640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    static inline void VisitSpecialized(Map* map, HeapObject* object) {}
415b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
4168640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    INLINE(static void Visit(Map* map, HeapObject* object)) {}
417b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  };
418b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
4198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void>
4208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      FixedArrayVisitor;
421fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
4228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void>
4238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      JSObjectVisitor;
424b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
4258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, void>
4268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      StructObjectVisitor;
427b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
428b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  typedef void (*Callback)(Map* map, HeapObject* object);
429b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
430b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  static VisitorDispatchTable<Callback> table_;
431b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org};
432b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
433b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
4348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgtemplate <typename StaticVisitor>
435b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgVisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
436b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    StaticMarkingVisitor<StaticVisitor>::table_;
437ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
438ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
4392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgclass WeakObjectRetainer;
4402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
4412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
4422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org// A weak list is single linked list where each element has a weak pointer to
4432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org// the next element. Given the head of the list, this function removes dead
4442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org// elements from the list and if requested records slots for next-element
4452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org// pointers. The template parameter T is a WeakListVisitor that defines how to
4462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org// access the next-element pointers.
4472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgtemplate <class T>
4481e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgObject* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer);
4498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
4508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}  // namespace v8::internal
451ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
452eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org#endif  // V8_OBJECTS_VISITING_H_
453