Chromium Code Reviews| Index: src/heap/objects-visiting.h |
| diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h |
| index abbb27a3267d7fba7618ccddf8930a93da667e50..c9d1c05c93c297cefa0aba3bbb193b33c62f870f 100644 |
| --- a/src/heap/objects-visiting.h |
| +++ b/src/heap/objects-visiting.h |
| @@ -24,10 +24,6 @@ |
| namespace v8 { |
| namespace internal { |
| - |
| -// Base class for all static visitors. |
| -class StaticVisitorBase : public AllStatic { |
| - public: |
| #define VISITOR_ID_LIST(V) \ |
| V(SeqOneByteString) \ |
| V(SeqTwoByteString) \ |
| @@ -37,7 +33,7 @@ class StaticVisitorBase : public AllStatic { |
| V(FreeSpace) \ |
| V(FixedArray) \ |
| V(FixedDoubleArray) \ |
| - V(FixedTypedArray) \ |
| + V(FixedTypedArrayBase) \ |
| V(FixedFloat64Array) \ |
| V(NativeContext) \ |
| V(AllocationSite) \ |
| @@ -63,22 +59,25 @@ class StaticVisitorBase : public AllStatic { |
| V(JSArrayBuffer) \ |
| V(JSRegExp) |
| - // For data objects, JS objects and structs along with generic visitor which |
| - // can visit object of any size we provide visitors specialized by |
| - // object size in words. |
| - // Ids of specialized visitors are declared in a linear order (without |
| - // holes) starting from the id of visitor specialized for 2 words objects |
| - // (base visitor id) and ending with the id of generic visitor. |
| - // Method GetVisitorIdForSize depends on this ordering to calculate visitor |
| - // id of specialized visitor from given instance size, base visitor id and |
| - // generic visitor's id. |
| - enum VisitorId { |
| +// For data objects, JS objects and structs along with generic visitor which |
| +// can visit object of any size we provide visitors specialized by |
| +// object size in words. |
| +// Ids of specialized visitors are declared in a linear order (without |
| +// holes) starting from the id of visitor specialized for 2 words objects |
| +// (base visitor id) and ending with the id of generic visitor. |
| +// Method GetVisitorIdForSize depends on this ordering to calculate visitor |
| +// id of specialized visitor from given instance size, base visitor id and |
| +// generic visitor's id. |
| +enum VisitorId { |
| #define VISITOR_ID_ENUM_DECL(id) kVisit##id, |
| - VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) |
| + VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) |
| #undef VISITOR_ID_ENUM_DECL |
| - kVisitorIdCount |
| - }; |
| + kVisitorIdCount |
| +}; |
| +// Base class for all static visitors. |
| +class StaticVisitorBase : public AllStatic { |
| + public: |
| // Visitor ID should fit in one byte. |
| STATIC_ASSERT(kVisitorIdCount <= 256); |
| @@ -99,24 +98,24 @@ class VisitorDispatchTable { |
| // We are not using memcpy to guarantee that during update |
| // every element of callbacks_ array will remain correct |
| // pointer (memcpy might be implemented as a byte copying loop). |
| - for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) { |
| + for (int i = 0; i < kVisitorIdCount; i++) { |
| base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]); |
| } |
| } |
| inline Callback GetVisitor(Map* map); |
| - inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) { |
| + inline Callback GetVisitorById(VisitorId id) { |
| return reinterpret_cast<Callback>(callbacks_[id]); |
| } |
| - void Register(StaticVisitorBase::VisitorId id, Callback callback) { |
| - DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. |
| + void Register(VisitorId id, Callback callback) { |
| + DCHECK(id < kVisitorIdCount); // id is unsigned. |
| callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); |
| } |
| private: |
| - base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; |
| + base::AtomicWord callbacks_[kVisitorIdCount]; |
| }; |
| @@ -349,10 +348,70 @@ template <typename StaticVisitor> |
| VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback> |
| StaticMarkingVisitor<StaticVisitor>::table_; |
| +#define TYPED_VISITOR_ID_LIST(V) \ |
| + V(AllocationSite) \ |
| + V(ByteArray) \ |
| + V(BytecodeArray) \ |
| + V(Cell) \ |
| + V(Code) \ |
| + V(ConsString) \ |
| + V(FixedArray) \ |
| + V(FixedDoubleArray) \ |
| + V(FixedFloat64Array) \ |
| + V(FixedTypedArrayBase) \ |
| + V(JSArrayBuffer) \ |
| + V(JSFunction) \ |
| + V(JSObject) \ |
| + V(JSRegExp) \ |
| + V(JSWeakCollection) \ |
| + V(Map) \ |
| + V(Oddball) \ |
| + V(PropertyCell) \ |
| + V(SeqOneByteString) \ |
| + V(SeqTwoByteString) \ |
| + V(SharedFunctionInfo) \ |
| + V(SlicedString) \ |
| + V(Symbol) \ |
| + V(TransitionArray) \ |
| + V(ThinString) \ |
| + V(WeakCell) |
| + |
| +// The base class for visitors that need to dispatch on object type. |
| +// It is similar to StaticVisitor except it uses virtual dispatch |
| +// instead of static dispatch table. The default behavour of all |
| +// visit functions is to iterate body of the given object using |
| +// the BodyDescriptor of the object. |
| +// |
| +// The visit functions return the size of the object cast to ResultType. |
| +// |
| +// This class is intended to be used in the following way: |
| +// |
| +// class SomeVisitor : public HeapVisitor<ResultType, SomeVisitor> { |
| +// ... |
| +// } |
| +// |
| +// This is an example of Curiously recurring template pattern. |
| +// TODO(ulan): replace static visitors with the HeapVisitor. |
| +template <typename ResultType, typename ConcreteVisitor> |
| +class HeapVisitor : public ObjectVisitor { |
| + public: |
| + ResultType IterateBody(HeapObject* object); |
| + |
| + protected: |
| +#define VISIT(type) virtual ResultType Visit##type(Map* map, type* object); |
| + TYPED_VISITOR_ID_LIST(VISIT) |
| +#undef VISIT |
| + virtual ResultType VisitShortcutCandidate(Map* map, ConsString* object); |
| + virtual ResultType VisitNativeContext(Map* map, Context* object); |
| + virtual ResultType VisitDataObject(Map* map, HeapObject* object); |
| + virtual ResultType VisitJSObjectFast(Map* map, JSObject* object); |
| + virtual ResultType VisitJSApiObject(Map* map, JSObject* object); |
| + virtual ResultType VisitStruct(Map* map, HeapObject* object); |
| + virtual ResultType VisitFreeSpace(Map* map, FreeSpace* object); |
|
Hannes Payer (out of office)
2017/04/27 14:29:50
Why can FreeSpace not be part of TYPED_VISITOR_ID_
ulan
2017/04/27 14:59:48
That would require FreeSpace::BodyDescriptor, whic
|
| +}; |
|
Hannes Payer (out of office)
2017/04/27 14:29:50
What would it take to generate all of them automat
ulan
2017/04/27 14:59:48
We would need the corresponding classes with BodyD
|
| class WeakObjectRetainer; |
| - |
| // A weak list is single linked list where each element has a weak pointer to |
| // the next element. Given the head of the list, this function removes dead |
| // elements from the list and if requested records slots for next-element |