Author: [EMAIL PROTECTED]
Date: Thu Dec 11 03:20:04 2008
New Revision: 965

Modified:
    branches/bleeding_edge/include/v8.h
    branches/bleeding_edge/src/api.cc
    branches/bleeding_edge/src/global-handles.cc
    branches/bleeding_edge/src/global-handles.h
    branches/bleeding_edge/src/mark-compact.cc
    branches/bleeding_edge/test/cctest/test-mark-compact.cc

Log:
Improve mark-compact object grouping interface.

The main goal was to improve O(n^2) behavior when there are many object  
groups.  The old API required the grouping to be done on the v8 side, along  
with a linear search.  The new interface requires the caller to do the  
grouping, passing V8 entire groups at a time.  This removes the group id  
concept on the v8 side.

   - Changed AddObjectToGroup to AddObjectGroup.
   - Removed the group id concept from the V8 side.
   - Remove a static constructor while I'm here, lazily initialize
     the object groups list.
   - Cleaned up return by non-const references to return pointers.

Review URL: http://codereview.chromium.org/13341

Modified: branches/bleeding_edge/include/v8.h
==============================================================================
--- branches/bleeding_edge/include/v8.h (original)
+++ branches/bleeding_edge/include/v8.h Thu Dec 11 03:20:04 2008
@@ -1967,10 +1967,10 @@
     * object in the group is alive, all objects in the group are alive.
     * After each garbage collection, object groups are removed. It is
     * intended to be used in the before-garbage-collection callback
-   * function for istance to simulate DOM tree connections among JS
+   * function, for instance to simulate DOM tree connections among JS
     * wrapper objects.
     */
-  static void AddObjectToGroup(void* id, Persistent<Object> obj);
+  static void AddObjectGroup(Persistent<Value>* objects, size_t length);

    /**
     * Initializes from snapshot if possible. Otherwise, attempts to

Modified: branches/bleeding_edge/src/api.cc
==============================================================================
--- branches/bleeding_edge/src/api.cc   (original)
+++ branches/bleeding_edge/src/api.cc   Thu Dec 11 03:20:04 2008
@@ -2641,9 +2641,10 @@
  }


-void V8::AddObjectToGroup(void* group_id, Persistent<Object> obj) {
-  if (IsDeadCheck("v8::V8::AddObjectToGroup()")) return;
-  i::GlobalHandles::AddToGroup(group_id,  
reinterpret_cast<i::Object**>(*obj));
+void V8::AddObjectGroup(Persistent<Value>* objects, size_t length) {
+  if (IsDeadCheck("v8::V8::AddObjectGroup()")) return;
+  STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
+  i::GlobalHandles::AddGroup(reinterpret_cast<i::Object***>(objects),  
length);
  }



Modified: branches/bleeding_edge/src/global-handles.cc
==============================================================================
--- branches/bleeding_edge/src/global-handles.cc        (original)
+++ branches/bleeding_edge/src/global-handles.cc        Thu Dec 11 03:20:04 2008
@@ -352,29 +352,26 @@

  #endif

-List<ObjectGroup*> GlobalHandles::object_groups_(4);
-
-void GlobalHandles::AddToGroup(void* id, Object** handle) {
-  for (int i = 0; i < object_groups_.length(); i++) {
-    ObjectGroup* entry = object_groups_[i];
-    if (entry->id_ == id) {
-      entry->objects_.Add(handle);
-      return;
-    }
-  }
+List<ObjectGroup*>* GlobalHandles::ObjectGroups() {
+  // Lazily initialize the list to avoid startup time static constructors.
+  static List<ObjectGroup*> groups(4);
+  return &groups;
+}

-  // not found
-  ObjectGroup* new_entry = new ObjectGroup(id);
-  new_entry->objects_.Add(handle);
-  object_groups_.Add(new_entry);
+void GlobalHandles::AddGroup(Object*** handles, size_t length) {
+  ObjectGroup* new_entry = new ObjectGroup(length);
+  for (size_t i = 0; i < length; ++i)
+    new_entry->objects_.Add(handles[i]);
+  ObjectGroups()->Add(new_entry);
  }


  void GlobalHandles::RemoveObjectGroups() {
-  for (int i = 0; i< object_groups_.length(); i++) {
-    delete object_groups_[i];
+  List<ObjectGroup*>* object_groups = ObjectGroups();
+  for (int i = 0; i< object_groups->length(); i++) {
+    delete object_groups->at(i);
    }
-  object_groups_.Clear();
+  object_groups->Clear();
  }



Modified: branches/bleeding_edge/src/global-handles.h
==============================================================================
--- branches/bleeding_edge/src/global-handles.h (original)
+++ branches/bleeding_edge/src/global-handles.h Thu Dec 11 03:20:04 2008
@@ -41,15 +41,14 @@
  // Callback function on handling weak global handles.
  // typedef bool (*WeakSlotCallback)(Object** pointer);

-// An object group is indexed by an id. 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 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 Malloced {
   public:
-  explicit ObjectGroup(void* id) : id_(id), objects_(4) {}
+  ObjectGroup() : objects_(4) {}
+  explicit ObjectGroup(size_t capacity) : objects_(capacity) {}

-  void* id_;
    List<Object**> objects_;
  };

@@ -102,15 +101,13 @@
    // Mark the weak pointers based on the callback.
    static void MarkWeakRoots(WeakSlotCallback f);

-  // Add an object to a group indexed by an id.
+  // Add an object group.
    // Should only used in GC callback function before a collection.
    // All groups are destroyed after a mark-compact collection.
-  static void AddToGroup(void* id, Object** location);
+  static void AddGroup(Object*** handles, size_t length);

    // Returns the object groups.
-  static List<ObjectGroup*>& ObjectGroups() {
-    return object_groups_;
-  }
+  static List<ObjectGroup*>* ObjectGroups();

    // Remove bags, this should only happen after GC.
    static void RemoveObjectGroups();
@@ -143,9 +140,6 @@
    static Node* first_free_;
    static Node* first_free() { return first_free_; }
    static void set_first_free(Node* value) { first_free_ = value; }
-
-  // A list of object groups.
-  static List<ObjectGroup*> object_groups_;
  };



Modified: branches/bleeding_edge/src/mark-compact.cc
==============================================================================
--- branches/bleeding_edge/src/mark-compact.cc  (original)
+++ branches/bleeding_edge/src/mark-compact.cc  Thu Dec 11 03:20:04 2008
@@ -564,10 +564,10 @@


  void MarkCompactCollector::MarkObjectGroups() {
-  List<ObjectGroup*>& object_groups = GlobalHandles::ObjectGroups();
+  List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups();

-  for (int i = 0; i < object_groups.length(); i++) {
-    ObjectGroup* entry = object_groups[i];
+  for (int i = 0; i < object_groups->length(); i++) {
+    ObjectGroup* entry = object_groups->at(i);
      if (entry == NULL) continue;

      List<Object**>& objects = entry->objects_;
@@ -591,8 +591,8 @@
      }
      // Once the entire group has been colored gray, set the object group
      // to NULL so it won't be processed again.
-    delete object_groups[i];
-    object_groups[i] = NULL;
+    delete object_groups->at(i);
+    object_groups->at(i) = NULL;
    }
  }


Modified: branches/bleeding_edge/test/cctest/test-mark-compact.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-mark-compact.cc     (original)
+++ branches/bleeding_edge/test/cctest/test-mark-compact.cc     Thu Dec 11  
03:20:04 2008
@@ -282,10 +282,12 @@
    Handle<FixedArray>::cast(g1s2)->set(0, *g2s2);
    Handle<FixedArray>::cast(g2s1)->set(0, *g1s1);

-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(1), g1s1.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(1), g1s2.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(2), g2s1.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(2), g2s2.location());
+  {
+    Object** g1_objects[] = { g1s1.location(), g1s2.location() };
+    Object** g2_objects[] = { g2s1.location(), g2s2.location() };
+    GlobalHandles::AddGroup(g1_objects, 2);
+    GlobalHandles::AddGroup(g2_objects, 2);
+  }
    // Do a full GC
    CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));

@@ -298,10 +300,12 @@
                            &WeakPointerCallback);

    // Groups are deleted, rebuild groups.
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(1), g1s1.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(1), g1s2.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(2), g2s1.location());
-  GlobalHandles::AddToGroup(reinterpret_cast<void*>(2), g2s2.location());
+  {
+    Object** g1_objects[] = { g1s1.location(), g1s2.location() };
+    Object** g2_objects[] = { g2s1.location(), g2s2.location() };
+    GlobalHandles::AddGroup(g1_objects, 2);
+    GlobalHandles::AddGroup(g2_objects, 2);
+  }

    CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to