Index: src/global-handles.h |
diff --git a/src/global-handles.h b/src/global-handles.h |
index 90707b0bc24b5067bc1d46155852b784406c9b70..81e14765c10a3e67e0207302408aff580b031b37 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 bookkeeping. |
+struct ObjectGroupConnection { |
+ ObjectGroupConnection(UniqueId id, Object** object) |
+ : id(id), object(object) {} |
+ |
+ bool operator==(const ObjectGroupConnection& other) const { |
+ return id == other.id; |
} |
- void Dispose() { |
- free(this); |
+ bool operator<(const ObjectGroupConnection& other) const { |
+ return id < other.id; |
} |
- HeapObject** parent_; |
- size_t length_; |
- Object** children_[1]; // Variable sized array. |
+ UniqueId id; |
+ Object** object; |
+}; |
- private: |
- void* operator new(size_t size); |
- void operator delete(void* p); |
- ~ImplicitRefGroup(); |
- DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup); |
+ |
+struct ObjectGroupRetainerInfo { |
+ ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info) |
+ : id(id), info(info) {} |
+ |
+ bool operator==(const ObjectGroupRetainerInfo& other) const { |
+ return id == other.id; |
+ } |
+ |
+ bool operator<(const ObjectGroupRetainerInfo& other) const { |
+ return id < other.id; |
+ } |
+ |
+ 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,23 @@ 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 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 SetReferenceFromGroup(UniqueId id, Object** child); |
+ |
+ // Adds an implicit reference from a parent object to a child object. Should |
+ // be only used in GC callback function before a collection. All implicit |
+ // references are destroyed after a mark-compact collection. |
+ void SetReference(HeapObject** parent, 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 +279,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 = 20; |
+ |
// Internal node structures. |
class Node; |
class NodeBlock; |
@@ -275,9 +313,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); |