Revision: 17253
Author:   [email protected]
Date:     Thu Oct 17 11:48:03 2013 UTC
Log: Enable calling the SetReference* & SetObjectGroupId functions with a Persistent<SubclassOfValue>.

This is needed for https://codereview.chromium.org/26792002/

BUG=
[email protected]

Review URL: https://codereview.chromium.org/27512003
http://code.google.com/p/v8/source/detail?r=17253

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Mon Oct 14 13:35:06 2013 UTC
+++ /branches/bleeding_edge/include/v8.h        Thu Oct 17 11:48:03 2013 UTC
@@ -712,6 +712,7 @@
   V8_INLINE T* operator*() const { return val_; }

  private:
+  friend class Isolate;
   friend class Utils;
   template<class F> friend class Handle;
   template<class F> friend class Local;
@@ -4066,8 +4067,8 @@
    * garbage collection types it is sufficient to provide object groups
    * for partially dependent handles only.
    */
-  void SetObjectGroupId(const Persistent<Value>& object,
-                        UniqueId id);
+  template<typename T> void SetObjectGroupId(const Persistent<T>& object,
+                                             UniqueId id);

   /**
* Allows the host application to declare implicit references from an object
@@ -4076,8 +4077,8 @@
* are removed. It is intended to be used in the before-garbage-collection
    * callback function.
    */
-  void SetReferenceFromGroup(UniqueId id,
-                             const Persistent<Value>& child);
+  template<typename T> void SetReferenceFromGroup(UniqueId id,
+ const Persistent<T>& child);

   /**
* Allows the host application to declare implicit references from an object
@@ -4085,8 +4086,8 @@
* too. After each garbage collection, all implicit references are removed. It * is intended to be used in the before-garbage-collection callback function.
    */
-  void SetReference(const Persistent<Object>& parent,
-                    const Persistent<Value>& child);
+  template<typename T, typename S>
+ void SetReference(const Persistent<T>& parent, const Persistent<S>& child);

   typedef void (*GCPrologueCallback)(Isolate* isolate,
                                      GCType type,
@@ -4140,8 +4141,11 @@
   Isolate& operator=(const Isolate&);
   void* operator new(size_t size);
   void operator delete(void*, size_t);
-};

+  void SetObjectGroupId(internal::Object** object, UniqueId id);
+  void SetReferenceFromGroup(UniqueId id, internal::Object** object);
+  void SetReference(internal::Object** parent, internal::Object** child);
+};

 class V8_EXPORT StartupData {
  public:
@@ -6418,6 +6422,33 @@
   typedef internal::Internals I;
   return I::GetEmbedderData(this);
 }
+
+
+template<typename T>
+void Isolate::SetObjectGroupId(const Persistent<T>& object,
+                               UniqueId id) {
+  TYPE_CHECK(Value, T);
+ SetObjectGroupId(reinterpret_cast<v8::internal::Object**>(object.val_), id);
+}
+
+
+template<typename T>
+void Isolate::SetReferenceFromGroup(UniqueId id,
+                                    const Persistent<T>& object) {
+  TYPE_CHECK(Value, T);
+  SetReferenceFromGroup(id,
+ reinterpret_cast<v8::internal::Object**>(object.val_));
+}
+
+
+template<typename T, typename S>
+void Isolate::SetReference(const Persistent<T>& parent,
+                           const Persistent<S>& child) {
+  TYPE_CHECK(Object, T);
+  TYPE_CHECK(Value, S);
+  SetReference(reinterpret_cast<v8::internal::Object**>(parent.val_),
+               reinterpret_cast<v8::internal::Object**>(child.val_));
+}


 Local<Value> Context::GetEmbedderData(int index) {
=======================================
--- /branches/bleeding_edge/src/api.cc  Mon Oct 14 12:41:28 2013 UTC
+++ /branches/bleeding_edge/src/api.cc  Thu Oct 17 11:48:03 2013 UTC
@@ -6350,31 +6350,32 @@
 }


-void Isolate::SetObjectGroupId(const Persistent<Value>& object,
-                               UniqueId id) {
+void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
   internal_isolate->global_handles()->SetObjectGroupId(
-      Utils::OpenPersistent(object).location(),
+      v8::internal::Handle<v8::internal::Object>(object).location(),
       id);
+  internal_isolate->global_handles()->SetObjectGroupId(object, id);
 }


-void Isolate::SetReferenceFromGroup(UniqueId id,
-                                    const Persistent<Value>& object) {
+void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
   internal_isolate->global_handles()->SetReferenceFromGroup(
       id,
-      Utils::OpenPersistent(object).location());
+      v8::internal::Handle<v8::internal::Object>(object).location());
+  internal_isolate->global_handles()->SetReferenceFromGroup(id, object);
 }


-void Isolate::SetReference(const Persistent<Object>& parent,
-                           const Persistent<Value>& child) {
+void Isolate::SetReference(internal::Object** parent,
+                           internal::Object** child) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
-  i::Object** parent_location = Utils::OpenPersistent(parent).location();
+  i::Object** parent_location =
+      v8::internal::Handle<v8::internal::Object>(parent).location();
   internal_isolate->global_handles()->SetReference(
       reinterpret_cast<i::HeapObject**>(parent_location),
-      Utils::OpenPersistent(child).location());
+      v8::internal::Handle<v8::internal::Object>(child).location());
 }


=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Tue Oct 15 08:59:26 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Oct 17 11:48:03 2013 UTC
@@ -3318,8 +3318,9 @@
 };


+template<typename T>
 static void WeakPointerCallback(v8::Isolate* isolate,
-                                Persistent<Value>* handle,
+                                Persistent<T>* handle,
                                 WeakCallCounter* counter) {
   CHECK_EQ(1234, counter->id());
   counter->increment();
@@ -3327,7 +3328,8 @@
 }


-static UniqueId MakeUniqueId(const Persistent<Value>& p) {
+template<typename T>
+static UniqueId MakeUniqueId(const Persistent<T>& p) {
return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
 }

@@ -3410,6 +3412,97 @@
     iso->SetObjectGroupId(g2s2, id2);
     iso->SetReferenceFromGroup(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(&counter, &WeakPointerCallback);
+  g2c1.MakeWeak(&counter, &WeakPointerCallback);
+
+  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+  CHECK_EQ(7, counter.NumberOfWeakCalls());
+}
+
+
+THREADED_TEST(ApiObjectGroupsForSubtypes) {
+  LocalContext env;
+  v8::Isolate* iso = env->GetIsolate();
+  HandleScope scope(iso);
+
+  Persistent<Object> g1s1;
+  Persistent<String> g1s2;
+  Persistent<String> g1c1;
+  Persistent<Object> g2s1;
+  Persistent<String> g2s2;
+  Persistent<String> g2c1;
+
+  WeakCallCounter counter(1234);
+
+  {
+    HandleScope scope(iso);
+    g1s1.Reset(iso, Object::New());
+    g1s2.Reset(iso, String::New("foo1"));
+    g1c1.Reset(iso, String::New("foo2"));
+    g1s1.MakeWeak(&counter, &WeakPointerCallback);
+    g1s2.MakeWeak(&counter, &WeakPointerCallback);
+    g1c1.MakeWeak(&counter, &WeakPointerCallback);
+
+    g2s1.Reset(iso, Object::New());
+    g2s2.Reset(iso, String::New("foo3"));
+    g2c1.Reset(iso, String::New("foo4"));
+    g2s1.MakeWeak(&counter, &WeakPointerCallback);
+    g2s2.MakeWeak(&counter, &WeakPointerCallback);
+    g2c1.MakeWeak(&counter, &WeakPointerCallback);
+  }
+
+  Persistent<Value> root(iso, g1s1);  // make a root.
+
+  // Connect group 1 and 2, make a cycle.
+  {
+    HandleScope scope(iso);
+ CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); + CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1)));
+  }
+
+  {
+    UniqueId id1 = MakeUniqueId(g1s1);
+    UniqueId id2 = MakeUniqueId(g2s2);
+    iso->SetObjectGroupId(g1s1, id1);
+    iso->SetObjectGroupId(g1s2, id1);
+    iso->SetReference(g1s1, g1c1);
+    iso->SetObjectGroupId(g2s1, id2);
+    iso->SetObjectGroupId(g2s2, id2);
+    iso->SetReferenceFromGroup(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(&counter, &WeakPointerCallback);
+  // But make children strong roots---all the objects (except for children)
+  // should be collectable now.
+  g1c1.ClearWeak();
+  g2c1.ClearWeak();
+
+  // Groups are deleted, rebuild groups.
+  {
+    UniqueId id1 = MakeUniqueId(g1s1);
+    UniqueId id2 = MakeUniqueId(g2s2);
+    iso->SetObjectGroupId(g1s1, id1);
+    iso->SetObjectGroupId(g1s2, id1);
+    iso->SetReference(g1s1, g1c1);
+    iso->SetObjectGroupId(g2s1, id2);
+    iso->SetObjectGroupId(g2s2, id2);
+    iso->SetReferenceFromGroup(id2, g2c1);
+  }

   heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to