Chromium Code Reviews| Index: src/global-handles.h |
| diff --git a/src/global-handles.h b/src/global-handles.h |
| index 90707b0bc24b5067bc1d46155852b784406c9b70..e8dc5c9bd12f397733302b4cc163bcf999703e20 100644 |
| --- a/src/global-handles.h |
| +++ b/src/global-handles.h |
| @@ -28,6 +28,7 @@ |
| #ifndef V8_GLOBAL_HANDLES_H_ |
| #define V8_GLOBAL_HANDLES_H_ |
| +#include "../include/v8.h" |
| #include "../include/v8-profiler.h" |
| #include "list.h" |
| @@ -46,70 +47,76 @@ class ObjectVisitor; |
| // At GC the destroyed global handles are removed from the free list |
| // and deallocated. |
| +// Data structures for tracking object groups and implicit references. |
| + |
| // An object group is treated like a single JS object: if one of object in |
| // the group is alive, all objects in the same group are considered alive. |
| // An object group is used to simulate object relationship in a DOM tree. |
| -class ObjectGroup { |
| - public: |
| - static ObjectGroup* New(Object*** handles, |
| - size_t length, |
| - v8::RetainedObjectInfo* info) { |
| + |
| +// An implicit references group consists of two parts: a parent object and a |
| +// list of children objects. If the parent is alive, all the children are alive |
| +// too. |
| + |
| +struct ObjectGroup { |
| + explicit ObjectGroup(size_t length) |
| + : info(NULL), length(length) { |
| ASSERT(length > 0); |
| - ObjectGroup* group = reinterpret_cast<ObjectGroup*>( |
| - malloc(OFFSET_OF(ObjectGroup, objects_[length]))); |
| - group->length_ = length; |
| - group->info_ = info; |
| - CopyWords(group->objects_, handles, static_cast<int>(length)); |
| - return group; |
| + objects = new Object**[length]; |
| } |
| + ~ObjectGroup(); |
| - void Dispose() { |
| - if (info_ != NULL) info_->Dispose(); |
| - free(this); |
| - } |
| + v8::RetainedObjectInfo* info; |
| + Object*** objects; |
| + size_t length; |
| +}; |
| - size_t length_; |
| - v8::RetainedObjectInfo* info_; |
| - Object** objects_[1]; // Variable sized array. |
| - private: |
| - void* operator new(size_t size); |
| - void operator delete(void* p); |
| - ~ObjectGroup(); |
| - DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGroup); |
| +struct ImplicitRefGroup { |
| + ImplicitRefGroup(HeapObject** parent, size_t length) |
| + : parent(parent), length(length) { |
| + ASSERT(length > 0); |
| + children = new Object**[length]; |
| + } |
| + ~ImplicitRefGroup(); |
| + |
| + HeapObject** parent; |
| + Object*** children; |
| + size_t length; |
| }; |
| -// An implicit references group consists of two parts: a parent object and |
| -// a list of children objects. If the parent is alive, all the children |
| -// are alive too. |
| -class ImplicitRefGroup { |
| - public: |
| - static ImplicitRefGroup* New(HeapObject** parent, |
| - Object*** children, |
| - size_t length) { |
| - ASSERT(length > 0); |
| - ImplicitRefGroup* group = reinterpret_cast<ImplicitRefGroup*>( |
| - malloc(OFFSET_OF(ImplicitRefGroup, children_[length]))); |
| - group->parent_ = parent; |
| - group->length_ = length; |
| - CopyWords(group->children_, children, length); |
| - return group; |
| +// For internal bookeeping. |
|
yurys
2013/04/22 14:39:54
typo: bookkeeping
marja
2013/04/23 12:00:05
Done.
|
| +struct ObjectGroupConnection { |
| + ObjectGroupConnection(UniqueId id, Object** object) |
| + : id(id), object(object) {} |
| + |
| + bool operator==(const ObjectGroupConnection& other) const { |
| + return id == other.id; |
| + } |
| + |
| + bool operator<(const ObjectGroupConnection& other) const { |
| + return id < other.id; |
| } |
| - void Dispose() { |
| - free(this); |
| + UniqueId id; |
| + Object** object; |
| +}; |
| + |
| + |
| +struct ObjectGroupRetainerInfo { |
| + ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info) |
| + : id(id), info(info) {} |
| + |
| + bool operator==(const ObjectGroupRetainerInfo& other) const { |
| + return id == other.id; |
| } |
| - HeapObject** parent_; |
| - size_t length_; |
| - Object** children_[1]; // Variable sized array. |
| + bool operator<(const ObjectGroupRetainerInfo& other) const { |
| + return id < other.id; |
| + } |
| - private: |
| - void* operator new(size_t size); |
| - void operator delete(void* p); |
| - ~ImplicitRefGroup(); |
| - DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup); |
| + UniqueId id; |
| + RetainedObjectInfo* info; |
| }; |
| @@ -218,6 +225,16 @@ class GlobalHandles { |
| size_t length, |
| v8::RetainedObjectInfo* info); |
| + // Associates handle with the object group represented by id. |
| + // Should be only used in GC callback function before a collection. |
| + // All groups are destroyed after a garbage collection. |
| + void SetObjectGroupId(Object** handle, UniqueId id); |
| + |
| + // Set RetainedObjectInfo for an object group. Should not be called more than |
| + // once for a group. Should not be called for a group which contains no |
| + // handles. |
| + void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info); |
| + |
| // Add an implicit references' group. |
| // Should be only used in GC callback function before a collection. |
| // All groups are destroyed after a mark-compact collection. |
| @@ -225,11 +242,19 @@ class GlobalHandles { |
| Object*** children, |
| size_t length); |
| - // Returns the object groups. |
| - List<ObjectGroup*>* object_groups() { return &object_groups_; } |
| + // Adds an implicit reference from a group (representative object of that |
| + // group) to an object. Should be only used in GC callback function before a |
| + // collection. All implicit references are destroyed after a mark-compact |
| + // collection. |
| + void AddImplicitReference(UniqueId id, Object** child); |
| + |
| + List<ObjectGroup*>* object_groups() { |
| + ComputeObjectGroupsAndImplicitReferences(); |
| + return &object_groups_; |
| + } |
| - // Returns the implicit references' groups. |
| List<ImplicitRefGroup*>* implicit_ref_groups() { |
| + ComputeObjectGroupsAndImplicitReferences(); |
| return &implicit_ref_groups_; |
| } |
| @@ -250,6 +275,15 @@ class GlobalHandles { |
| private: |
| explicit GlobalHandles(Isolate* isolate); |
| + // Migrates data from the internal representation (object_group_connections_, |
| + // retainer_infos_ and implicit_ref_connections_) to the public and more |
| + // efficient representation (object_groups_ and implicit_ref_groups_). |
| + void ComputeObjectGroupsAndImplicitReferences(); |
| + |
| + // v8::internal::List is inefficient even for small number of elements, if we |
| + // don't assign any initial capacity. |
| + static const int kObjectGroupConnectionsCapacity; |
| + |
| // Internal node structures. |
| class Node; |
| class NodeBlock; |
| @@ -275,9 +309,17 @@ class GlobalHandles { |
| int post_gc_processing_count_; |
| + // Object groups and implicit references, public and more efficient |
| + // representation. |
| List<ObjectGroup*> object_groups_; |
| List<ImplicitRefGroup*> implicit_ref_groups_; |
| + // Object groups and implicit references, temporary representation while |
| + // constructing the groups. |
| + List<ObjectGroupConnection> object_group_connections_; |
| + List<ObjectGroupRetainerInfo> retainer_infos_; |
| + List<ObjectGroupConnection> implicit_ref_connections_; |
| + |
| friend class Isolate; |
| DISALLOW_COPY_AND_ASSIGN(GlobalHandles); |