Revert the commits adding new GC-related APIs.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Apr 2013 16:37:04 +0000 (16:37 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Apr 2013 16:37:04 +0000 (16:37 +0000)
We need to solve efficiency problems first.

This reverts the following revisions: 14283 14286 14221 14215

BUG=

Review URL: https://codereview.chromium.org/14294009

Patch from Marja Hölttä <marja@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14293 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
src/global-handles.cc
src/global-handles.h
src/heap-snapshot-generator.cc
src/mark-compact.cc
test/cctest/test-api.cc
test/cctest/test-global-handles.cc
test/cctest/test-heap-profiler.cc
test/cctest/test-mark-compact.cc

index b40a4bf..e1c0203 100644 (file)
@@ -144,28 +144,6 @@ class Isolate;
 class Object;
 }
 
-// Generic-purpose unique identifier.
-class UniqueId {
- public:
-  explicit UniqueId(intptr_t data)
-      : data_(data) {}
-
-  bool operator==(const UniqueId& other) const {
-    return data_ == other.data_;
-  }
-
-  bool operator!=(const UniqueId& other) const {
-    return data_ != other.data_;
-  }
-
-  bool operator<(const UniqueId& other) const {
-    return data_ < other.data_;
-  }
-
- private:
-  intptr_t data_;
-};
-
 
 // --- Weak Handles ---
 
@@ -3536,8 +3514,6 @@ class V8EXPORT V8 {
    * for partially dependent handles only.
    * See v8-profiler.h for RetainedObjectInfo interface description.
    */
-  // TODO(marja): deprecate AddObjectGroup. Use SetObjectGroupID and
-  // SetRetainedObjectInfo instead.
   static void AddObjectGroup(Persistent<Value>* objects,
                              size_t length,
                              RetainedObjectInfo* info = NULL);
@@ -3546,23 +3522,6 @@ class V8EXPORT V8 {
                              size_t length,
                              RetainedObjectInfo* info = NULL);
 
-  static void SetObjectGroupId(Isolate* isolate,
-                               const Persistent<Value>& object,
-                               UniqueId id);
-
-  static void SetRetainedObjectInfo(Isolate* isolate,
-                                    UniqueId id,
-                                    RetainedObjectInfo* info);
-
-  /**
-   * Sets a representative object to a group. Used in conjunction with implicit
-   * references: If you're going to use AddImplicitReference with the group, you
-   * need to set a representative object too.
-   */
-  static void SetObjectGroupRepresentative(Isolate* isolate,
-                                           UniqueId id,
-                                           const Persistent<Object>& object);
-
   /**
    * Allows the host application to declare implicit references between
    * the objects: if |parent| is alive, all |children| are alive too.
@@ -3570,24 +3529,11 @@ class V8EXPORT V8 {
    * are removed.  It is intended to be used in the before-garbage-collection
    * callback function.
    */
-  // TODO(marja): Deprecate AddImplicitReferences. Use
-  // SetObjectGroupRepresentativeObject and AddImplicitReference instead.
   static void AddImplicitReferences(Persistent<Object> parent,
                                     Persistent<Value>* children,
                                     size_t length);
 
   /**
-   * Allows the host application to declare implicit references. If the
-   * representative object of the object group (identified by id) is alive, the
-   * children are alive too. After each garbage collection, all implicit
-   * references are removed. It is intended to be used in the
-   * before-garbage-collection callback function.
-   */
-  static void AddImplicitReference(Isolate* isolate,
-                                   UniqueId id,
-                                   const Persistent<Value>& object);
-
-  /**
    * Initializes from snapshot if possible. Otherwise, attempts to
    * initialize from scratch.  This function is called implicitly if
    * you use the API without calling it first.
index a9e01e0..dddcd7d 100644 (file)
@@ -5925,34 +5925,6 @@ void V8::AddObjectGroup(Isolate* exported_isolate,
 }
 
 
-void V8::SetObjectGroupId(Isolate* exported_isolate,
-                          const Persistent<Value>& object,
-                          UniqueId id) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
-  isolate->global_handles()->SetObjectGroupId(
-      reinterpret_cast<i::Object**>(*object), id);
-}
-
-
-void V8::SetRetainedObjectInfo(Isolate* exported_isolate,
-                               UniqueId id,
-                               RetainedObjectInfo* info) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
-  isolate->global_handles()->SetRetainedObjectInfo(id, info);
-}
-
-
-void V8::SetObjectGroupRepresentative(
-      Isolate* exported_isolate,
-      UniqueId id,
-      const Persistent<Object>& object) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
-  isolate->global_handles()->SetObjectGroupRepresentative(
-      id,
-      i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*object)).location());
-}
-
-
 void V8::AddImplicitReferences(Persistent<Object> parent,
                                Persistent<Value>* children,
                                size_t length) {
@@ -5965,15 +5937,6 @@ void V8::AddImplicitReferences(Persistent<Object> parent,
 }
 
 
-void V8::AddImplicitReference(Isolate* exported_isolate,
-                              UniqueId id,
-                              const Persistent<Value>& object) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
-  isolate->global_handles()
-      ->AddImplicitReference(id, reinterpret_cast<i::Object**>(*object));
-}
-
-
 intptr_t Isolate::AdjustAmountOfExternalAllocatedMemory(
     intptr_t change_in_bytes) {
   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
index a3e7f1e..cb3115a 100644 (file)
@@ -36,6 +36,11 @@ namespace v8 {
 namespace internal {
 
 
+ObjectGroup::~ObjectGroup() {
+  if (info_ != NULL) info_->Dispose();
+}
+
+
 class GlobalHandles::Node {
  public:
   // State transition diagram:
@@ -573,77 +578,45 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
 
 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
                                         WeakSlotCallbackWithHeap can_skip) {
-  if (object_groups_.length() == 0)
-    return false;
-
-  object_groups_.Sort();
-  retainer_infos_.Sort();
-
-  // During the iteration, some of the elements of object_groups are
-  // deleted. This is done by moving surviving elements at the front of the list
-  // and deleting from the end. This index tracks where the next surviving
-  // element should be moved.
-  int surviving_element_index = 0;
-  int info_index = 0;  // For iterating retainer_infos_.
-  int surviving_info_index = 0;
-
-  UniqueId current_group_id(0);
-  int current_group_start = 0;
+  int last = 0;
   bool any_group_was_visited = false;
-
-  for (int i = 0; i <= object_groups_.length(); ++i) {
-    if (i == 0)
-      current_group_id = object_groups_[i].id;
-    if (i == object_groups_.length() ||
-        current_group_id != object_groups_[i].id) {
-      // Group detected: objects in indices [current_group_start, i[.
-      bool group_should_be_visited = false;
-      for (int j = current_group_start; j < i; ++j) {
-        Object* object = *(object_groups_[j].object);
-        if (object->IsHeapObject()) {
-          if (!can_skip(isolate_->heap(), &object)) {
-            group_should_be_visited = true;
-            break;
-          }
+  for (int i = 0; i < object_groups_.length(); i++) {
+    ObjectGroup* entry = object_groups_.at(i);
+    ASSERT(entry != NULL);
+
+    Object*** objects = entry->objects_;
+    bool group_should_be_visited = false;
+    for (size_t j = 0; j < entry->length_; j++) {
+      Object* object = *objects[j];
+      if (object->IsHeapObject()) {
+        if (!can_skip(isolate_->heap(), &object)) {
+          group_should_be_visited = true;
+          break;
         }
       }
+    }
 
-      if (!group_should_be_visited) {
-        for (int j = current_group_start; j < i; ++j)
-          object_groups_[surviving_element_index++] = object_groups_[j];
-      } else {
-        // An object in the group requires visiting, so iterate over all
-        // objects in the group.
-        for (int j = current_group_start; j < i; ++j) {
-          Object* object = *(object_groups_[j].object);
-          if (object->IsHeapObject()) {
-            v->VisitPointer(&object);
-            any_group_was_visited = true;
-          }
-        }
-      }
+    if (!group_should_be_visited) {
+      object_groups_[last++] = entry;
+      continue;
+    }
 
-      if (info_index < retainer_infos_.length() &&
-          retainer_infos_[info_index].id ==
-          object_groups_[current_group_start].id) {
-        // This object group has an associated ObjectGroupRetainerInfo.
-        if (!group_should_be_visited) {
-          retainer_infos_[surviving_info_index++] =
-              retainer_infos_[info_index];
-        } else if (retainer_infos_[info_index].info != NULL) {
-          retainer_infos_[info_index].info->Dispose();
-          retainer_infos_[info_index].info = NULL;
-        }
-        ++info_index;
-      }
-      if (i < object_groups_.length()) {
-        current_group_id = object_groups_[i].id;
-        current_group_start = i;
+    // An object in the group requires visiting, so iterate over all
+    // objects in the group.
+    for (size_t j = 0; j < entry->length_; ++j) {
+      Object* object = *objects[j];
+      if (object->IsHeapObject()) {
+        v->VisitPointer(&object);
+        any_group_was_visited = true;
       }
     }
+
+    // Once the entire group has been iterated over, set the object
+    // group to NULL so it won't be processed again.
+    entry->Dispose();
+    object_groups_.at(i) = NULL;
   }
-  object_groups_.Rewind(surviving_element_index);
-  retainer_infos_.Rewind(surviving_info_index);
+  object_groups_.Rewind(last);
   return any_group_was_visited;
 }
 
@@ -851,42 +824,9 @@ void GlobalHandles::AddObjectGroup(Object*** handles,
     if (info != NULL) info->Dispose();
     return;
   }
-  for (size_t i = 0; i < length; ++i) {
-    object_groups_.Add(ObjectGroupConnection(
-        UniqueId(reinterpret_cast<intptr_t>(handles[0])), handles[i]));
-  }
-  for (size_t i = 0; i < length; ++i) {
-    if ((*handles[i])->IsHeapObject()) {
-      representative_objects_.Add(ObjectGroupRepresentative(
-          UniqueId(reinterpret_cast<intptr_t>(handles[0])),
-          reinterpret_cast<HeapObject**>(handles[i])));
-      break;
-    }
-  }
-  if (info != NULL) {
-    retainer_infos_.Add(ObjectGroupRetainerInfo(
-        UniqueId(reinterpret_cast<intptr_t>(handles[0])), info));
-  }
+  object_groups_.Add(ObjectGroup::New(handles, length, info));
 }
 
-void GlobalHandles::SetObjectGroupId(Object** handle,
-                                     UniqueId id) {
-  object_groups_.Add(ObjectGroupConnection(id, handle));
-}
-
-
-void GlobalHandles::SetRetainedObjectInfo(UniqueId id,
-                                          RetainedObjectInfo* info) {
-  retainer_infos_.Add(ObjectGroupRetainerInfo(id, info));
-}
-
-
-void GlobalHandles::SetObjectGroupRepresentative(
-    UniqueId id,
-    HeapObject** representative_object) {
-  representative_objects_.Add(
-      ObjectGroupRepresentative(id, representative_object));
-}
 
 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
                                           Object*** children,
@@ -897,31 +837,23 @@ void GlobalHandles::AddImplicitReferences(HeapObject** parent,
     ASSERT(!Node::FromLocation(children[i])->is_independent());
   }
 #endif
-  for (size_t i = 0; i < length; ++i) {
-    implicit_ref_groups_.Add(ObjectGroupConnection(
-        UniqueId(reinterpret_cast<intptr_t>(parent)), children[i]));
-  }
-}
-
-
-void GlobalHandles::AddImplicitReference(UniqueId id, Object** child) {
-  ASSERT(!Node::FromLocation(child)->is_independent());
-  implicit_ref_groups_.Add(ObjectGroupConnection(id, child));
+  if (length == 0) return;
+  implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
 }
 
 
 void GlobalHandles::RemoveObjectGroups() {
-  object_groups_.Clear();
-  for (int i = 0; i < retainer_infos_.length(); ++i) {
-    if (retainer_infos_[i].info != NULL)
-      retainer_infos_[i].info->Dispose();
+  for (int i = 0; i < object_groups_.length(); i++) {
+    object_groups_.at(i)->Dispose();
   }
-  retainer_infos_.Clear();
+  object_groups_.Clear();
 }
 
 
 void GlobalHandles::RemoveImplicitRefGroups() {
-  representative_objects_.Clear();
+  for (int i = 0; i < implicit_ref_groups_.length(); i++) {
+    implicit_ref_groups_.at(i)->Dispose();
+  }
   implicit_ref_groups_.Clear();
 }
 
index 7697364..90707b0 100644 (file)
@@ -28,7 +28,6 @@
 #ifndef V8_GLOBAL_HANDLES_H_
 #define V8_GLOBAL_HANDLES_H_
 
-#include "../include/v8.h"
 #include "../include/v8-profiler.h"
 
 #include "list.h"
@@ -47,64 +46,70 @@ 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.
-
-// 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 ObjectGroupConnection {
-  ObjectGroupConnection(UniqueId id, Object** object)
-      : id(id), object(object) {}
-
-  bool operator==(const ObjectGroupConnection& other) const {
-    return id == other.id;
+class ObjectGroup {
+ public:
+  static ObjectGroup* New(Object*** handles,
+                          size_t length,
+                          v8::RetainedObjectInfo* info) {
+    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;
   }
 
-  bool operator<(const ObjectGroupConnection& other) const {
-    return id < other.id;
+  void Dispose() {
+    if (info_ != NULL) info_->Dispose();
+    free(this);
   }
 
-  UniqueId id;
-  Object** object;
-};
-
-
-struct ObjectGroupRetainerInfo {
-  ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info)
-      : id(id), info(info) {}
+  size_t length_;
+  v8::RetainedObjectInfo* info_;
+  Object** objects_[1];  // Variable sized array.
 
-  bool operator==(const ObjectGroupRetainerInfo& other) const {
-    return id == other.id;
-  }
-
-  bool operator<(const ObjectGroupRetainerInfo& other) const {
-    return id < other.id;
-  }
-
-  UniqueId id;
-  RetainedObjectInfo* info;
+ private:
+  void* operator new(size_t size);
+  void operator delete(void* p);
+  ~ObjectGroup();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGroup);
 };
 
 
-struct ObjectGroupRepresentative {
-  ObjectGroupRepresentative(UniqueId id, HeapObject** object)
-      : id(id), object(object) {}
-
-  bool operator==(const ObjectGroupRepresentative& other) const {
-    return id == other.id;
+// 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;
   }
 
-  bool operator<(const ObjectGroupRepresentative& other) const {
-    return id < other.id;
+  void Dispose() {
+    free(this);
   }
 
-  UniqueId id;
-  HeapObject** object;
+  HeapObject** parent_;
+  size_t length_;
+  Object** children_[1];  // Variable sized array.
+
+ private:
+  void* operator new(size_t size);
+  void operator delete(void* p);
+  ~ImplicitRefGroup();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup);
 };
 
 
@@ -213,22 +218,6 @@ 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);
-
-  // Sets a representative object 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 SetObjectGroupRepresentative(UniqueId id,
-                                    HeapObject** representative_object);
-
   // 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.
@@ -236,28 +225,14 @@ class GlobalHandles {
                              Object*** children,
                              size_t length);
 
-  // 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);
+  // Returns the object groups.
+  List<ObjectGroup*>* object_groups() { return &object_groups_; }
 
-  List<ObjectGroupConnection>* object_groups() {
-    return &object_groups_;
-  }
-
-  List<ObjectGroupRetainerInfo>* retainer_infos() {
-    return &retainer_infos_;
-  }
-
-  List<ObjectGroupConnection>* implicit_ref_groups() {
+  // Returns the implicit references' groups.
+  List<ImplicitRefGroup*>* implicit_ref_groups() {
     return &implicit_ref_groups_;
   }
 
-  List<ObjectGroupRepresentative>* representative_objects() {
-    return &representative_objects_;
-  }
-
   // Remove bags, this should only happen after GC.
   void RemoveObjectGroups();
   void RemoveImplicitRefGroups();
@@ -300,13 +275,8 @@ class GlobalHandles {
 
   int post_gc_processing_count_;
 
-  // Object groups.
-  List<ObjectGroupConnection> object_groups_;
-  List<ObjectGroupRetainerInfo> retainer_infos_;
-  List<ObjectGroupRepresentative> representative_objects_;
-
-  // Implicit references.
-  List<ObjectGroupConnection> implicit_ref_groups_;
+  List<ObjectGroup*> object_groups_;
+  List<ImplicitRefGroup*> implicit_ref_groups_;
 
   friend class Isolate;
 
index 6e03b0c..d22239f 100644 (file)
@@ -1940,43 +1940,17 @@ void NativeObjectsExplorer::FillRetainedObjects() {
   const GCType major_gc_type = kGCTypeMarkSweepCompact;
   // Record objects that are joined into ObjectGroups.
   isolate->heap()->CallGCPrologueCallbacks(major_gc_type);
-
-  List<ObjectGroupConnection>* groups =
-      isolate->global_handles()->object_groups();
-  List<ObjectGroupRetainerInfo>* infos =
-      isolate->global_handles()->retainer_infos();
-  groups->Sort();
-  infos->Sort();
-
-  int info_index = 0;
-  UniqueId current_group_id(0);
-  int current_group_start = 0;
-
-  if (groups->length() > 0) {
-    for (int i = 0; i <= groups->length(); ++i) {
-      if (i == 0)
-        current_group_id = groups->at(i).id;
-      if (i == groups->length() ||
-          current_group_id != groups->at(i).id) {
-        // Group detected: objects in indices [current_group_start, i[.
-        if (info_index < infos->length() &&
-            infos->at(info_index).id == groups->at(current_group_start).id) {
-          // Transfer the ownership of info.
-          List<HeapObject*>* list =
-              GetListMaybeDisposeInfo(infos->at(info_index).info);
-          infos->at(info_index).info = NULL;
-          for (int j = current_group_start; j < i; ++j) {
-            HeapObject* obj = HeapObject::cast(*(groups->at(j).object));
-            list->Add(obj);
-            in_groups_.Insert(obj);
-          }
-        }
-        if (i < groups->length()) {
-          current_group_id = groups->at(i).id;
-          current_group_start = i;
-        }
-      }
+  List<ObjectGroup*>* groups = isolate->global_handles()->object_groups();
+  for (int i = 0; i < groups->length(); ++i) {
+    ObjectGroup* group = groups->at(i);
+    if (group->info_ == NULL) continue;
+    List<HeapObject*>* list = GetListMaybeDisposeInfo(group->info_);
+    for (size_t j = 0; j < group->length_; ++j) {
+      HeapObject* obj = HeapObject::cast(*group->objects_[j]);
+      list->Add(obj);
+      in_groups_.Insert(obj);
     }
+    group->info_ = NULL;  // Acquire info object ownership.
   }
   isolate->global_handles()->RemoveObjectGroups();
   isolate->heap()->CallGCEpilogueCallbacks(major_gc_type);
@@ -1988,61 +1962,24 @@ void NativeObjectsExplorer::FillRetainedObjects() {
 
 void NativeObjectsExplorer::FillImplicitReferences() {
   Isolate* isolate = Isolate::Current();
-  List<ObjectGroupConnection>* ref_groups =
+  List<ImplicitRefGroup*>* groups =
       isolate->global_handles()->implicit_ref_groups();
-  List<ObjectGroupRepresentative>* representative_objects =
-      isolate->global_handles()->representative_objects();
-
-  if (ref_groups->length() == 0)
-    return;
-
-  ref_groups->Sort();
-  representative_objects->Sort();
-
-  int representative_objects_index = 0;
-  UniqueId current_group_id(0);
-  int current_group_start = 0;
-  for (int i = 0; i <= ref_groups->length(); ++i) {
-    if (i == 0)
-      current_group_id = ref_groups->at(i).id;
-    if (i == ref_groups->length() || current_group_id != ref_groups->at(i).id) {
-      // Group detected: objects in indices [current_group_start, i[.
-
-      // Find the representative object for this group.
-      while (representative_objects_index < representative_objects->length() &&
-             representative_objects->at(representative_objects_index).id <
-             current_group_id)
-        ++representative_objects_index;
-
-      if (representative_objects_index < representative_objects->length() &&
-          representative_objects->at(representative_objects_index).id ==
-              current_group_id) {
-        HeapObject* parent =
-            *(representative_objects->at(representative_objects_index).object);
-
-        int parent_entry =
-            filler_->FindOrAddEntry(parent, native_entries_allocator_)->index();
-        ASSERT(parent_entry != HeapEntry::kNoEntry);
-
-        for (int j = current_group_start; j < i; ++j) {
-          Object* child = *(ref_groups->at(j).object);
-          HeapEntry* child_entry =
-              filler_->FindOrAddEntry(child, native_entries_allocator_);
-          filler_->SetNamedReference(
-              HeapGraphEdge::kInternal,
-              parent_entry,
-              "native",
-              child_entry);
-        }
-      } else {
-        // This should not happen: representative object for a group was not
-        // set!
-        UNREACHABLE();
-      }
-      if (i < ref_groups->length()) {
-        current_group_id = ref_groups->at(i).id;
-        current_group_start = i;
-      }
+  for (int i = 0; i < groups->length(); ++i) {
+    ImplicitRefGroup* group = groups->at(i);
+    HeapObject* parent = *group->parent_;
+    int parent_entry =
+        filler_->FindOrAddEntry(parent, native_entries_allocator_)->index();
+    ASSERT(parent_entry != HeapEntry::kNoEntry);
+    Object*** children = group->children_;
+    for (size_t j = 0; j < group->length_; ++j) {
+      Object* child = *children[j];
+      HeapEntry* child_entry =
+          filler_->FindOrAddEntry(child, native_entries_allocator_);
+      filler_->SetNamedReference(
+          HeapGraphEdge::kInternal,
+          parent_entry,
+          "native",
+          child_entry);
     }
   }
   isolate->global_handles()->RemoveImplicitRefGroups();
index 165c03f..f49179f 100644 (file)
@@ -1931,72 +1931,34 @@ void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
 
 
 void MarkCompactCollector::MarkImplicitRefGroups() {
-  Isolate* isolate = Isolate::Current();
-  List<ObjectGroupConnection>* ref_groups =
-      isolate->global_handles()->implicit_ref_groups();
-  List<ObjectGroupRepresentative>* representative_objects =
-      isolate->global_handles()->representative_objects();
-
-  if (ref_groups->length() == 0)
-    return;
-
-  ref_groups->Sort();
-  representative_objects->Sort();
-
-  int surviving_ref_group_index = 0;
-  int surviving_representative_object_index = 0;
-
-  int representative_objects_index = 0;
-  UniqueId current_group_id(0);
-  int current_group_start = 0;
-  for (int i = 0; i <= ref_groups->length(); ++i) {
-    if (i == 0)
-      current_group_id = ref_groups->at(i).id;
-    if (i == ref_groups->length() || current_group_id != ref_groups->at(i).id) {
-      // Group detected: objects in indices [current_group_start, i[.
-
-      // Find the representative object for this group.
-      while (representative_objects_index < representative_objects->length() &&
-             representative_objects->at(representative_objects_index).id <
-             current_group_id)
-        ++representative_objects_index;
-
-      if (representative_objects_index < representative_objects->length() &&
-          representative_objects->at(representative_objects_index).id ==
-              current_group_id) {
-        HeapObject* parent =
-            *(representative_objects->at(representative_objects_index).object);
-
-        if (!IsMarked(parent)) {
-          // Nothing tbd, copy the reference group so that it can be iterated
-          // during the next call.
-          for (int j = current_group_start; j < i; ++j)
-            ref_groups->at(surviving_ref_group_index++) = ref_groups->at(j);
-          representative_objects->at(surviving_representative_object_index++) =
-              representative_objects->at(representative_objects_index);
-        } else {
-          // A parent object is marked, so mark all child heap objects.
-          for (int j = current_group_start; j < i; ++j) {
-            if ((*ref_groups->at(j).object)->IsHeapObject()) {
-              HeapObject* child = HeapObject::cast(*ref_groups->at(j).object);
-              MarkBit mark = Marking::MarkBitFrom(child);
-              MarkObject(child, mark);
-            }
-          }
-        }
-      } else {
-        // This should not happen: representative object for a group was not
-        // set!
-        UNREACHABLE();
-      }
-      if (i < ref_groups->length()) {
-        current_group_id = ref_groups->at(i).id;
-        current_group_start = i;
+  List<ImplicitRefGroup*>* ref_groups =
+      isolate()->global_handles()->implicit_ref_groups();
+
+  int last = 0;
+  for (int i = 0; i < ref_groups->length(); i++) {
+    ImplicitRefGroup* entry = ref_groups->at(i);
+    ASSERT(entry != NULL);
+
+    if (!IsMarked(*entry->parent_)) {
+      (*ref_groups)[last++] = entry;
+      continue;
+    }
+
+    Object*** children = entry->children_;
+    // A parent object is marked, so mark all child heap objects.
+    for (size_t j = 0; j < entry->length_; ++j) {
+      if ((*children[j])->IsHeapObject()) {
+        HeapObject* child = HeapObject::cast(*children[j]);
+        MarkBit mark = Marking::MarkBitFrom(child);
+        MarkObject(child, mark);
       }
     }
+
+    // Once the entire group has been marked, dispose it because it's
+    // not needed anymore.
+    entry->Dispose();
   }
-  ref_groups->Rewind(surviving_ref_group_index);
-  representative_objects->Rewind(surviving_representative_object_index);
+  ref_groups->Rewind(last);
 }
 
 
index e4f523e..acc47b9 100644 (file)
@@ -67,7 +67,6 @@ using ::v8::StackTrace;
 using ::v8::String;
 using ::v8::TryCatch;
 using ::v8::Undefined;
-using ::v8::UniqueId;
 using ::v8::V8;
 using ::v8::Value;
 
@@ -2446,7 +2445,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
 }
 
 
-THREADED_TEST(OldApiObjectGroups) {
+THREADED_TEST(ApiObjectGroups) {
   LocalContext env;
   v8::Isolate* iso = env->GetIsolate();
   HandleScope scope(iso);
@@ -2491,7 +2490,7 @@ THREADED_TEST(OldApiObjectGroups) {
     V8::AddObjectGroup(g1_objects, 2);
     V8::AddImplicitReferences(g1s1, g1_children, 1);
     V8::AddObjectGroup(g2_objects, 2);
-    V8::AddImplicitReferences(g2s1, g2_children, 1);
+    V8::AddImplicitReferences(g2s2, g2_children, 1);
   }
   // Do a single full GC, ensure incremental marking is stopped.
   HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -2515,7 +2514,7 @@ THREADED_TEST(OldApiObjectGroups) {
     V8::AddObjectGroup(g1_objects, 2);
     V8::AddImplicitReferences(g1s1, g1_children, 1);
     V8::AddObjectGroup(g2_objects, 2);
-    V8::AddImplicitReferences(g2s1, g2_children, 1);
+    V8::AddImplicitReferences(g2s2, g2_children, 1);
   }
 
   HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -2532,99 +2531,7 @@ THREADED_TEST(OldApiObjectGroups) {
 }
 
 
-THREADED_TEST(ApiObjectGroups) {
-  LocalContext env;
-  v8::Isolate* iso = env->GetIsolate();
-  HandleScope scope(iso);
-
-  Persistent<Object> g1s1;
-  Persistent<Object> g1s2;
-  Persistent<Object> g1c1;
-  Persistent<Object> g2s1;
-  Persistent<Object> g2s2;
-  Persistent<Object> g2c1;
-
-  WeakCallCounter counter(1234);
-
-  {
-    HandleScope scope(iso);
-    g1s1 = Persistent<Object>::New(iso, Object::New());
-    g1s2 = Persistent<Object>::New(iso, Object::New());
-    g1c1 = Persistent<Object>::New(iso, Object::New());
-    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-
-    g2s1 = Persistent<Object>::New(iso, Object::New());
-    g2s2 = Persistent<Object>::New(iso, Object::New());
-    g2c1 = Persistent<Object>::New(iso, Object::New());
-    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  }
-
-  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);  // make a root.
-
-  // Connect group 1 and 2, make a cycle.
-  CHECK(g1s2->Set(0, g2s2));
-  CHECK(g2s1->Set(0, g1s1));
-
-  {
-    UniqueId id1(reinterpret_cast<intptr_t>(*g1s1));
-    UniqueId id2(reinterpret_cast<intptr_t>(*g2s2));
-    V8::SetObjectGroupId(iso, g1s1, id1);
-    V8::SetObjectGroupId(iso, g1s2, id1);
-    V8::SetObjectGroupRepresentative(iso, id1, g1s1);
-    V8::AddImplicitReference(iso, id1, g1c1);
-    V8::SetObjectGroupId(iso, g2s1, id2);
-    V8::SetObjectGroupId(iso, g2s2, id2);
-    V8::SetObjectGroupRepresentative(iso, id2, g2s1);
-    V8::AddImplicitReference(iso, id2, g2c1);
-  }
-  // Do a single full GC, ensure incremental marking is stopped.
-  v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
-      iso)->heap();
-  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
-  // All object should be alive.
-  CHECK_EQ(0, counter.NumberOfWeakCalls());
-
-  // Weaken the root.
-  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  // But make children strong roots---all the objects (except for children)
-  // should be collectable now.
-  g1c1.ClearWeak(iso);
-  g2c1.ClearWeak(iso);
-
-  // Groups are deleted, rebuild groups.
-  {
-    UniqueId id1(reinterpret_cast<intptr_t>(*g1s1));
-    UniqueId id2(reinterpret_cast<intptr_t>(*g2s2));
-    V8::SetObjectGroupId(iso, g1s1, id1);
-    V8::SetObjectGroupId(iso, g1s2, id1);
-    V8::SetObjectGroupRepresentative(iso, id1, g1s1);
-    V8::AddImplicitReference(iso, id1, g1c1);
-    V8::SetObjectGroupId(iso, g2s1, id2);
-    V8::SetObjectGroupId(iso, g2s2, id2);
-    V8::SetObjectGroupRepresentative(iso, id2, g2s1);
-    V8::AddImplicitReference(iso, id2, g2c1);
-  }
-
-  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
-  // All objects should be gone. 5 global handles in total.
-  CHECK_EQ(5, counter.NumberOfWeakCalls());
-
-  // And now make children weak again and collect them.
-  g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-
-  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-  CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
-THREADED_TEST(OldApiObjectGroupsCycle) {
+THREADED_TEST(ApiObjectGroupsCycle) {
   LocalContext env;
   v8::Isolate* iso = env->GetIsolate();
   HandleScope scope(iso);
@@ -2730,125 +2637,9 @@ THREADED_TEST(OldApiObjectGroupsCycle) {
 }
 
 
-THREADED_TEST(ApiObjectGroupsCycle) {
-  LocalContext env;
-  v8::Isolate* iso = env->GetIsolate();
-  HandleScope scope(iso);
-
-  WeakCallCounter counter(1234);
-
-  Persistent<Object> g1s1;
-  Persistent<Object> g1s2;
-  Persistent<Object> g2s1;
-  Persistent<Object> g2s2;
-  Persistent<Object> g3s1;
-  Persistent<Object> g3s2;
-  Persistent<Object> g4s1;
-  Persistent<Object> g4s2;
-
-  {
-    HandleScope scope(iso);
-    g1s1 = Persistent<Object>::New(iso, Object::New());
-    g1s2 = Persistent<Object>::New(iso, Object::New());
-    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g1s1.IsWeak(iso));
-    CHECK(g1s2.IsWeak(iso));
-
-    g2s1 = Persistent<Object>::New(iso, Object::New());
-    g2s2 = Persistent<Object>::New(iso, Object::New());
-    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g2s1.IsWeak(iso));
-    CHECK(g2s2.IsWeak(iso));
-
-    g3s1 = Persistent<Object>::New(iso, Object::New());
-    g3s2 = Persistent<Object>::New(iso, Object::New());
-    g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g3s1.IsWeak(iso));
-    CHECK(g3s2.IsWeak(iso));
-
-    g4s1 = Persistent<Object>::New(iso, Object::New());
-    g4s2 = Persistent<Object>::New(iso, Object::New());
-    g4s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g4s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g4s1.IsWeak(iso));
-    CHECK(g4s2.IsWeak(iso));
-  }
-
-  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);  // make a root.
-
-  // Connect groups.  We're building the following cycle:
-  // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
-  // groups.
-  {
-    UniqueId id1(reinterpret_cast<intptr_t>(*g1s1));
-    UniqueId id2(reinterpret_cast<intptr_t>(*g2s1));
-    UniqueId id3(reinterpret_cast<intptr_t>(*g3s1));
-    UniqueId id4(reinterpret_cast<intptr_t>(*g4s1));
-    V8::SetObjectGroupId(iso, g1s1, id1);
-    V8::SetObjectGroupId(iso, g1s2, id1);
-    V8::SetObjectGroupRepresentative(iso, id1, g1s1);
-    V8::AddImplicitReference(iso, id1, g2s1);
-    V8::SetObjectGroupId(iso, g2s1, id2);
-    V8::SetObjectGroupId(iso, g2s2, id2);
-    V8::SetObjectGroupRepresentative(iso, id2, g2s1);
-    V8::AddImplicitReference(iso, id2, g3s1);
-    V8::SetObjectGroupId(iso, g3s1, id3);
-    V8::SetObjectGroupId(iso, g3s2, id3);
-    V8::SetObjectGroupRepresentative(iso, id3, g3s1);
-    V8::AddImplicitReference(iso, id3, g4s1);
-    V8::SetObjectGroupId(iso, g4s1, id4);
-    V8::SetObjectGroupId(iso, g4s2, id4);
-    V8::SetObjectGroupRepresentative(iso, id4, g4s1);
-    V8::AddImplicitReference(iso, id4, g1s1);
-  }
-  // Do a single full GC
-  v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
-      iso)->heap();
-  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
-  // All object should be alive.
-  CHECK_EQ(0, counter.NumberOfWeakCalls());
-
-  // Weaken the root.
-  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-
-  // Groups are deleted, rebuild groups.
-  {
-    UniqueId id1(reinterpret_cast<intptr_t>(*g1s1));
-    UniqueId id2(reinterpret_cast<intptr_t>(*g2s1));
-    UniqueId id3(reinterpret_cast<intptr_t>(*g3s1));
-    UniqueId id4(reinterpret_cast<intptr_t>(*g4s1));
-    V8::SetObjectGroupId(iso, g1s1, id1);
-    V8::SetObjectGroupId(iso, g1s2, id1);
-    V8::SetObjectGroupRepresentative(iso, id1, g1s1);
-    V8::AddImplicitReference(iso, id1, g2s1);
-    V8::SetObjectGroupId(iso, g2s1, id2);
-    V8::SetObjectGroupId(iso, g2s2, id2);
-    V8::SetObjectGroupRepresentative(iso, id2, g2s1);
-    V8::AddImplicitReference(iso, id2, g3s1);
-    V8::SetObjectGroupId(iso, g3s1, id3);
-    V8::SetObjectGroupId(iso, g3s2, id3);
-    V8::SetObjectGroupRepresentative(iso, id3, g3s1);
-    V8::AddImplicitReference(iso, id3, g4s1);
-    V8::SetObjectGroupId(iso, g4s1, id4);
-    V8::SetObjectGroupId(iso, g4s2, id4);
-    V8::SetObjectGroupRepresentative(iso, id4, g4s1);
-    V8::AddImplicitReference(iso, id4, g1s1);
-  }
-
-  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
-  // All objects should be gone. 9 global handles in total.
-  CHECK_EQ(9, counter.NumberOfWeakCalls());
-}
-
-
 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures
 // on the buildbots, so was made non-threaded for the time being.
-TEST(OldApiObjectGroupsCycleForScavenger) {
+TEST(ApiObjectGroupsCycleForScavenger) {
   i::FLAG_stress_compaction = false;
   i::FLAG_gc_global = false;
   LocalContext env;
@@ -2943,105 +2734,6 @@ TEST(OldApiObjectGroupsCycleForScavenger) {
 }
 
 
-// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
-// on the buildbots, so was made non-threaded for the time being.
-TEST(ApiObjectGroupsCycleForScavenger) {
-  i::FLAG_stress_compaction = false;
-  i::FLAG_gc_global = false;
-  LocalContext env;
-  v8::Isolate* iso = env->GetIsolate();
-  HandleScope scope(iso);
-
-  WeakCallCounter counter(1234);
-
-  Persistent<Object> g1s1;
-  Persistent<Object> g1s2;
-  Persistent<Object> g2s1;
-  Persistent<Object> g2s2;
-  Persistent<Object> g3s1;
-  Persistent<Object> g3s2;
-
-  {
-    HandleScope scope(iso);
-    g1s1 = Persistent<Object>::New(iso, Object::New());
-    g1s2 = Persistent<Object>::New(iso, Object::New());
-    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-
-    g2s1 = Persistent<Object>::New(iso, Object::New());
-    g2s2 = Persistent<Object>::New(iso, Object::New());
-    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-
-    g3s1 = Persistent<Object>::New(iso, Object::New());
-    g3s2 = Persistent<Object>::New(iso, Object::New());
-    g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  }
-
-  // Make a root.
-  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);
-  root.MarkPartiallyDependent(iso);
-
-  // Connect groups.  We're building the following cycle:
-  // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
-  // groups.
-  {
-    g1s1.MarkPartiallyDependent(iso);
-    g1s2.MarkPartiallyDependent(iso);
-    g2s1.MarkPartiallyDependent(iso);
-    g2s2.MarkPartiallyDependent(iso);
-    g3s1.MarkPartiallyDependent(iso);
-    g3s2.MarkPartiallyDependent(iso);
-    V8::SetObjectGroupId(iso, g1s1, UniqueId(1));
-    V8::SetObjectGroupId(iso, g1s2, UniqueId(1));
-    g1s1->Set(v8_str("x"), g2s1);
-    V8::SetObjectGroupId(iso, g2s1, UniqueId(2));
-    V8::SetObjectGroupId(iso, g2s2, UniqueId(2));
-    g2s1->Set(v8_str("x"), g3s1);
-    V8::SetObjectGroupId(iso, g3s1, UniqueId(3));
-    V8::SetObjectGroupId(iso, g3s2, UniqueId(3));
-    g3s1->Set(v8_str("x"), g1s1);
-  }
-
-  v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
-      iso)->heap();
-  heap->CollectGarbage(i::NEW_SPACE);
-
-  // All objects should be alive.
-  CHECK_EQ(0, counter.NumberOfWeakCalls());
-
-  // Weaken the root.
-  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  root.MarkPartiallyDependent(iso);
-
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
-  // Groups are deleted, rebuild groups.
-  {
-    g1s1.MarkPartiallyDependent(isolate);
-    g1s2.MarkPartiallyDependent(isolate);
-    g2s1.MarkPartiallyDependent(isolate);
-    g2s2.MarkPartiallyDependent(isolate);
-    g3s1.MarkPartiallyDependent(isolate);
-    g3s2.MarkPartiallyDependent(isolate);
-    V8::SetObjectGroupId(iso, g1s1, UniqueId(1));
-    V8::SetObjectGroupId(iso, g1s2, UniqueId(1));
-    g1s1->Set(v8_str("x"), g2s1);
-    V8::SetObjectGroupId(iso, g2s1, UniqueId(2));
-    V8::SetObjectGroupId(iso, g2s2, UniqueId(2));
-    g2s1->Set(v8_str("x"), g3s1);
-    V8::SetObjectGroupId(iso, g3s1, UniqueId(3));
-    V8::SetObjectGroupId(iso, g3s2, UniqueId(3));
-    g3s1->Set(v8_str("x"), g1s1);
-  }
-
-  heap->CollectGarbage(i::NEW_SPACE);
-
-  // All objects should be gone. 7 global handles in total.
-  CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
 THREADED_TEST(ScriptException) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
index 324ea8d..1959a40 100644 (file)
@@ -30,7 +30,6 @@
 #include "cctest.h"
 
 using namespace v8::internal;
-using v8::UniqueId;
 
 static int NumberOfWeakCalls = 0;
 static void WeakPointerCallback(v8::Isolate* isolate,
@@ -197,115 +196,3 @@ TEST(IterateObjectGroupsOldApi) {
     ASSERT(info2.has_been_disposed());
   }
 }
-
-TEST(IterateObjectGroups) {
-  CcTest::InitializeVM();
-  GlobalHandles* global_handles = Isolate::Current()->global_handles();
-
-  v8::HandleScope handle_scope(CcTest::isolate());
-
-  Handle<Object> g1s1 =
-      global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g1s2 =
-      global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
-  global_handles->MakeWeak(g1s1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g1s2.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-
-  Handle<Object> g2s1 =
-      global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g2s2 =
-    global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
-  global_handles->MakeWeak(g2s1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g2s2.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-
-  TestRetainedObjectInfo info1;
-  TestRetainedObjectInfo info2;
-  {
-    global_handles->SetObjectGroupId(g2s1.location(), UniqueId(2));
-    global_handles->SetObjectGroupId(g2s2.location(), UniqueId(2));
-    global_handles->SetRetainedObjectInfo(UniqueId(2), &info2);
-    global_handles->SetObjectGroupId(g1s1.location(), UniqueId(1));
-    global_handles->SetObjectGroupId(g1s2.location(), UniqueId(1));
-    global_handles->SetRetainedObjectInfo(UniqueId(1), &info1);
-  }
-
-  // Iterate the object groups. First skip all.
-  {
-    ResetCanSkipData();
-    skippable_objects.Add(*g1s1.location());
-    skippable_objects.Add(*g1s2.location());
-    skippable_objects.Add(*g2s1.location());
-    skippable_objects.Add(*g2s2.location());
-    TestObjectVisitor visitor;
-    global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
-
-    // CanSkipCallback was called for all objects.
-    ASSERT(can_skip_called_objects.length() == 4);
-    ASSERT(can_skip_called_objects.Contains(*g1s1.location()));
-    ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
-    ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
-    ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
-
-    // Nothing was visited.
-    ASSERT(visitor.visited.length() == 0);
-    ASSERT(!info1.has_been_disposed());
-    ASSERT(!info2.has_been_disposed());
-  }
-
-  // Iterate again, now only skip the second object group.
-  {
-    ResetCanSkipData();
-    // The first grough should still be visited, since only one object is
-    // skipped.
-    skippable_objects.Add(*g1s1.location());
-    skippable_objects.Add(*g2s1.location());
-    skippable_objects.Add(*g2s2.location());
-    TestObjectVisitor visitor;
-    global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
-
-    // CanSkipCallback was called for all objects.
-    ASSERT(can_skip_called_objects.length() == 3 ||
-           can_skip_called_objects.length() == 4);
-    ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
-    ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
-    ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
-
-    // The first group was visited.
-    ASSERT(visitor.visited.length() == 2);
-    ASSERT(visitor.visited.Contains(*g1s1.location()));
-    ASSERT(visitor.visited.Contains(*g1s2.location()));
-    ASSERT(info1.has_been_disposed());
-    ASSERT(!info2.has_been_disposed());
-  }
-
-  // Iterate again, don't skip anything.
-  {
-    ResetCanSkipData();
-    TestObjectVisitor visitor;
-    global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
-
-    // CanSkipCallback was called for all objects.
-    fprintf(stderr, "can skip len %d\n", can_skip_called_objects.length());
-    ASSERT(can_skip_called_objects.length() == 1);
-    ASSERT(can_skip_called_objects.Contains(*g2s1.location()) ||
-           can_skip_called_objects.Contains(*g2s2.location()));
-
-    // The second group was visited.
-    ASSERT(visitor.visited.length() == 2);
-    ASSERT(visitor.visited.Contains(*g2s1.location()));
-    ASSERT(visitor.visited.Contains(*g2s2.location()));
-    ASSERT(info2.has_been_disposed());
-  }
-}
index ff2838c..59e7b8f 100644 (file)
@@ -1191,10 +1191,9 @@ class GraphWithImplicitRefs {
   explicit GraphWithImplicitRefs(LocalContext* env) {
     CHECK_EQ(NULL, instance_);
     instance_ = this;
-    isolate_ = (*env)->GetIsolate();
+    v8::Isolate* isolate = (*env)->GetIsolate();
     for (int i = 0; i < kObjectsCount; i++) {
-      objects_[i] =
-          v8::Persistent<v8::Object>::New(isolate_, v8::Object::New());
+      objects_[i] = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
     }
     (*env)->Global()->Set(v8_str("root_object"), objects_[0]);
   }
@@ -1209,35 +1208,15 @@ class GraphWithImplicitRefs {
  private:
   void AddImplicitReferences() {
     // 0 -> 1
-    v8::V8::SetObjectGroupId(isolate_,
-                             v8::Persistent<v8::Object>::Cast(objects_[0]),
-                             v8::UniqueId(1));
-    v8::V8::SetObjectGroupRepresentative(
-        isolate_,
-        v8::UniqueId(1),
-        v8::Persistent<v8::Object>::Cast(objects_[0]));
-    v8::V8::AddImplicitReference(isolate_,
-                                 v8::UniqueId(1),
-                                 v8::Persistent<v8::Object>::Cast(objects_[1]));
+    v8::V8::AddImplicitReferences(
+        v8::Persistent<v8::Object>::Cast(objects_[0]), &objects_[1], 1);
     // Adding two more references(note length=2 in params): 1 -> 2, 1 -> 3
-    v8::V8::SetObjectGroupId(isolate_,
-                             v8::Persistent<v8::Object>::Cast(objects_[1]),
-                             v8::UniqueId(2));
-    v8::V8::SetObjectGroupRepresentative(
-        isolate_,
-        v8::UniqueId(2),
-        v8::Persistent<v8::Object>::Cast(objects_[1]));
-    v8::V8::AddImplicitReference(isolate_,
-                                 v8::UniqueId(2),
-                                 v8::Persistent<v8::Object>::Cast(objects_[2]));
-    v8::V8::AddImplicitReference(isolate_,
-                                 v8::UniqueId(2),
-                                 v8::Persistent<v8::Object>::Cast(objects_[3]));
+    v8::V8::AddImplicitReferences(
+        v8::Persistent<v8::Object>::Cast(objects_[1]), &objects_[2], 2);
   }
 
   v8::Persistent<v8::Value> objects_[kObjectsCount];
   static GraphWithImplicitRefs* instance_;
-  v8::Isolate* isolate_;
 };
 
 GraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL;
index ee1481f..db8c3e4 100644 (file)
@@ -43,8 +43,6 @@
 
 using namespace v8::internal;
 
-using v8::UniqueId;
-
 
 TEST(MarkingDeque) {
   CcTest::InitializeVM();
@@ -308,7 +306,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
   handle.Dispose(isolate);
 }
 
-TEST(ObjectGroupsOldApi) {
+TEST(ObjectGroups) {
   FLAG_incremental_marking = false;
   CcTest::InitializeVM();
   GlobalHandles* global_handles = Isolate::Current()->global_handles();
@@ -370,7 +368,7 @@ TEST(ObjectGroupsOldApi) {
         Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
     global_handles->AddObjectGroup(g2_objects, 2, NULL);
     global_handles->AddImplicitReferences(
-        Handle<HeapObject>::cast(g2s1).location(), g2_children, 1);
+        Handle<HeapObject>::cast(g2s2).location(), g2_children, 1);
   }
   // Do a full GC
   HEAP->CollectGarbage(OLD_POINTER_SPACE);
@@ -399,7 +397,7 @@ TEST(ObjectGroupsOldApi) {
         Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
     global_handles->AddObjectGroup(g2_objects, 2, NULL);
     global_handles->AddImplicitReferences(
-        Handle<HeapObject>::cast(g2s1).location(), g2_children, 1);
+        Handle<HeapObject>::cast(g2s2).location(), g2_children, 1);
   }
 
   HEAP->CollectGarbage(OLD_POINTER_SPACE);
@@ -421,122 +419,6 @@ TEST(ObjectGroupsOldApi) {
   CHECK_EQ(7, NumberOfWeakCalls);
 }
 
-TEST(ObjectGroups) {
-  FLAG_incremental_marking = false;
-  CcTest::InitializeVM();
-  GlobalHandles* global_handles = reinterpret_cast<v8::internal::Isolate*>(
-      CcTest::isolate())->global_handles();
-
-  NumberOfWeakCalls = 0;
-  v8::HandleScope handle_scope(CcTest::isolate());
-
-  Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
-      CcTest::isolate())->heap();
-  Handle<Object> g1s1 =
-      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g1s2 =
-      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g1c1 =
-      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  global_handles->MakeWeak(g1s1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g1s2.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g1c1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-
-  Handle<Object> g2s1 =
-      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g2s2 =
-    global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  Handle<Object> g2c1 =
-    global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
-  global_handles->MakeWeak(g2s1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g2s2.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g2c1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-
-  Handle<Object> root = global_handles->Create(*g1s1);  // make a root.
-
-  // Connect group 1 and 2, make a cycle.
-  Handle<FixedArray>::cast(g1s2)->set(0, *g2s2);
-  Handle<FixedArray>::cast(g2s1)->set(0, *g1s1);
-
-  {
-    global_handles->SetObjectGroupId(g1s1.location(), v8::UniqueId(1));
-    global_handles->SetObjectGroupId(g1s2.location(), v8::UniqueId(1));
-    global_handles->SetObjectGroupRepresentative(
-        v8::UniqueId(1), reinterpret_cast<HeapObject**>(g1s1.location()));
-    global_handles->AddImplicitReference(v8::UniqueId(1), g1c1.location());
-    global_handles->SetObjectGroupId(g2s1.location(), v8::UniqueId(2));
-    global_handles->SetObjectGroupId(g2s2.location(), v8::UniqueId(2));
-    global_handles->SetObjectGroupRepresentative(
-        v8::UniqueId(2), reinterpret_cast<HeapObject**>(g2s1.location()));
-    global_handles->AddImplicitReference(v8::UniqueId(2), g2c1.location());
-  }
-  // Do a full GC
-  heap->CollectGarbage(OLD_POINTER_SPACE);
-
-  // All object should be alive.
-  CHECK_EQ(0, NumberOfWeakCalls);
-
-  // Weaken the root.
-  global_handles->MakeWeak(root.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  // But make children strong roots---all the objects (except for children)
-  // should be collectable now.
-  global_handles->ClearWeakness(g1c1.location());
-  global_handles->ClearWeakness(g2c1.location());
-
-  // Groups are deleted, rebuild groups.
-  {
-    global_handles->SetObjectGroupId(g1s1.location(), v8::UniqueId(1));
-    global_handles->SetObjectGroupId(g1s2.location(), v8::UniqueId(1));
-    global_handles->SetObjectGroupRepresentative(
-        v8::UniqueId(1), reinterpret_cast<HeapObject**>(g1s1.location()));
-    global_handles->AddImplicitReference(v8::UniqueId(1), g1c1.location());
-    global_handles->SetObjectGroupId(g2s1.location(), v8::UniqueId(2));
-    global_handles->SetObjectGroupId(g2s2.location(), v8::UniqueId(2));
-    global_handles->SetObjectGroupRepresentative(
-        v8::UniqueId(2), reinterpret_cast<HeapObject**>(g2s1.location()));
-    global_handles->AddImplicitReference(v8::UniqueId(2), g2c1.location());
-  }
-
-  heap->CollectGarbage(OLD_POINTER_SPACE);
-
-  // All objects should be gone. 5 global handles in total.
-  CHECK_EQ(5, NumberOfWeakCalls);
-
-  // And now make children weak again and collect them.
-  global_handles->MakeWeak(g1c1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-  global_handles->MakeWeak(g2c1.location(),
-                           reinterpret_cast<void*>(1234),
-                           NULL,
-                           &WeakPointerCallback);
-
-  heap->CollectGarbage(OLD_POINTER_SPACE);
-  CHECK_EQ(7, NumberOfWeakCalls);
-}
-
 
 class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
  public:
@@ -562,7 +444,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
 };
 
 
-TEST(EmptyObjectGroupsOldApi) {
+TEST(EmptyObjectGroups) {
   CcTest::InitializeVM();
   GlobalHandles* global_handles = Isolate::Current()->global_handles();