Revision: 13496
Author:   [email protected]
Date:     Thu Jan 24 07:53:16 2013
Log:      Implement VisitHandlesInNewSpaceWithClassIds()

BUG=
TEST=test-api.cc::PersistentHandleInNewSpaceVisitor

Review URL: https://codereview.chromium.org/11365131
Patch from Kentaro Hara <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13496

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/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Wed Jan 23 23:54:40 2013
+++ /branches/bleeding_edge/include/v8.h        Thu Jan 24 07:53:16 2013
@@ -3488,6 +3488,16 @@
    */
   static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);

+  /**
+ * Iterates through all the persistent handles in the current isolate's heap + * that have class_ids and are candidates to be marked as partially dependent + * handles. This will visit handles to young objects created since the last
+   * garbage collection but is free to visit an arbitrary superset of these
+   * objects.
+   */
+  static void VisitHandlesForPartialDependence(
+      Isolate* isolate, PersistentHandleVisitor* visitor);
+
   /**
    * Optional notification that the embedder is idle.
    * V8 uses the notification to reduce memory footprint.
=======================================
--- /branches/bleeding_edge/src/api.cc  Thu Jan 17 06:31:03 2013
+++ /branches/bleeding_edge/src/api.cc  Thu Jan 24 07:53:16 2013
@@ -4495,30 +4495,47 @@
 }


+class VisitorAdapter : public i::ObjectVisitor {
+ public:
+  explicit VisitorAdapter(PersistentHandleVisitor* visitor)
+      : visitor_(visitor) {}
+  virtual void VisitPointers(i::Object** start, i::Object** end) {
+    UNREACHABLE();
+  }
+  virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+    visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
+                                    class_id);
+  }
+ private:
+  PersistentHandleVisitor* visitor_;
+};
+
+
 void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::V8::VisitHandlesWithClassId");

   i::AssertNoAllocation no_allocation;

-  class VisitorAdapter : public i::ObjectVisitor {
-   public:
-    explicit VisitorAdapter(PersistentHandleVisitor* visitor)
-        : visitor_(visitor) {}
-    virtual void VisitPointers(i::Object** start, i::Object** end) {
-      UNREACHABLE();
-    }
-    virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
- visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
-                                      class_id);
-    }
-   private:
-    PersistentHandleVisitor* visitor_;
-  } visitor_adapter(visitor);
+  VisitorAdapter visitor_adapter(visitor);
   isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
 }


+void v8::V8::VisitHandlesForPartialDependence(
+    Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
+  ASSERT(isolate == i::Isolate::Current());
+  IsDeadCheck(isolate, "v8::V8::VisitHandlesForPartialDependence");
+
+  i::AssertNoAllocation no_allocation;
+
+  VisitorAdapter visitor_adapter(visitor);
+  isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
+      &visitor_adapter);
+}
+
+
 bool v8::V8::IdleNotification(int hint) {
   // Returning true tells the caller that it need not
   // continue to call IdleNotification.
@@ -5447,11 +5464,11 @@
 }


-void V8::AddObjectGroup(Isolate* exportedIsolate,
+void V8::AddObjectGroup(Isolate* exported_isolate,
                         Persistent<Value>* objects,
                         size_t length,
                         RetainedObjectInfo* info) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exportedIsolate);
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
   ASSERT(isolate == i::Isolate::Current());
   if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
   STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
=======================================
--- /branches/bleeding_edge/src/global-handles.cc       Mon Jan 21 04:31:13 2013
+++ /branches/bleeding_edge/src/global-handles.cc       Thu Jan 24 07:53:16 2013
@@ -680,6 +680,17 @@
     }
   }
 }
+
+
+void GlobalHandles::IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v) {
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    if (node->IsRetainer() && node->has_wrapper_class_id()) {
+      v->VisitEmbedderReference(node->location(),
+                                node->wrapper_class_id());
+    }
+  }
+}


 int GlobalHandles::NumberOfWeakHandles() {
=======================================
--- /branches/bleeding_edge/src/global-handles.h        Mon Jan 21 04:31:13 2013
+++ /branches/bleeding_edge/src/global-handles.h        Thu Jan 24 07:53:16 2013
@@ -173,6 +173,10 @@
   // Iterates over all handles that have embedder-assigned class ID.
   void IterateAllRootsWithClassIds(ObjectVisitor* v);

+  // Iterates over all handles in the new space that have embedder-assigned
+  // class ID.
+  void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v);
+
   // Iterates over all weak roots in heap.
   void IterateWeakRoots(ObjectVisitor* v);

=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Jan 17 23:20:17 2013
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Thu Jan 24 07:53:16 2013
@@ -16697,6 +16697,32 @@
   CHECK_EQ(65535, object.WrapperClassId());
   object.Dispose();
 }
+
+
+TEST(PersistentHandleInNewSpaceVisitor) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Persistent<v8::Object> object1 =
+      v8::Persistent<v8::Object>::New(v8::Object::New());
+  CHECK_EQ(0, object1.WrapperClassId());
+  object1.SetWrapperClassId(42);
+  CHECK_EQ(42, object1.WrapperClassId());
+
+  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+  v8::Persistent<v8::Object> object2 =
+      v8::Persistent<v8::Object>::New(v8::Object::New());
+  CHECK_EQ(0, object2.WrapperClassId());
+  object2.SetWrapperClassId(42);
+  CHECK_EQ(42, object2.WrapperClassId());
+
+  Visitor42 visitor(object2);
+ v8::V8::VisitHandlesForPartialDependence(v8::Isolate::GetCurrent(), &visitor);
+  CHECK_EQ(1, visitor.counter_);
+
+  object1.Dispose();
+  object2.Dispose();
+}


 TEST(RegExp) {

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


Reply via email to