bug 819215 - make NS_IMPL_CYCLE_COLLECTION_XXXCLASS unnecessary r=smaug, mccr8
authorTrevor Saunders <trev.saunders@gmail.com>
Sat, 08 Dec 2012 00:08:37 -0500
changeset 121764 5ef3d98bc229120f1bb126e32817a62daf52639d
parent 121763 a80379c23cffa90223bc6f2305479a4bba936310
child 121765 0804d5dc440396026da5d11397c225069d2c2146
push idunknown
push userunknown
push dateunknown
reviewerssmaug, mccr8
bugs819215
milestone20.0a1
bug 819215 - make NS_IMPL_CYCLE_COLLECTION_XXXCLASS unnecessary r=smaug, mccr8
js/xpconnect/src/xpcprivate.h
xpcom/base/nsAgg.h
xpcom/glue/nsCycleCollectionNoteChild.h
xpcom/glue/nsCycleCollectionParticipant.h
xpcom/glue/nsISupportsImpl.h
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2613,18 +2613,25 @@ public:
     class NS_CYCLE_COLLECTION_INNERCLASS
      : public nsXPCOMCycleCollectionParticipant
     {
       NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(XPCWrappedNative,
                                                     XPCWrappedNative)
       static NS_METHOD RootImpl(void *p) { return NS_OK; }
       static NS_METHOD UnlinkImpl(void *p);
       static NS_METHOD UnrootImpl(void *p) { return NS_OK; }
+      static nsXPCOMCycleCollectionParticipant* GetParticipant()
+      {
+        static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)>
+          ::Type participant =
+          { NS_IMPL_CYCLE_COLLECTION_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)) };
+        return NS_PARTICIPANT_AS(nsXPCOMCycleCollectionParticipant,
+                                 &participant);
+      }
     };
-    NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
     NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative)
 
     nsIPrincipal* GetObjectPrincipal() const;
 
     JSBool
     IsValid() const {return nullptr != mFlatJSObject;}
 
 #define XPC_SCOPE_WORD(s)   (intptr_t(s))
--- a/xpcom/base/nsAgg.h
+++ b/xpcom/base/nsAgg.h
@@ -83,18 +83,26 @@ public:                                 
   static _class* Downcast(nsISupports* s)                                   \
   {                                                                         \
     return (_class*)((char*)(s) - offsetof(_class, fAggregated));           \
   }                                                                         \
   static nsISupports* Upcast(_class *p)                                     \
   {                                                                         \
     return p->InnerObject();                                                \
   }                                                                         \
-};                                                                          \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  static nsXPCOMCycleCollectionParticipant* GetParticipant()                   \
+  {                                                                            \
+    static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>    \
+    ::Type participant = {                                                     \
+      NS_IMPL_CYCLE_COLLECTION_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class))   \
+    };                                                                         \
+    return NS_PARTICIPANT_AS(nsXPCOMCycleCollectionParticipant,                \
+                                    &participant);                             \
+  }                                                                            \
+};
 
 // Put this in your class's constructor:
 #define NS_INIT_AGGREGATED(outer)                                           \
   PR_BEGIN_MACRO                                                            \
     fOuter = outer ? outer : &fAggregated;                                  \
   PR_END_MACRO
 
 
--- a/xpcom/glue/nsCycleCollectionNoteChild.h
+++ b/xpcom/glue/nsCycleCollectionNoteChild.h
@@ -36,17 +36,17 @@ CycleCollectionNoteEdgeName(nsCycleColle
 
 #define NS_CYCLE_COLLECTION_INNERCLASS                                         \
         cycleCollection
 
 #define NS_CYCLE_COLLECTION_INNERNAME                                          \
         _cycleCollectorGlobal
 
 #define NS_CYCLE_COLLECTION_PARTICIPANT(_class)                                \
-        _class::NS_CYCLE_COLLECTION_INNERNAME.GetParticipant()
+        _class::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant()
 
 template <typename T>
 nsISupports* ToSupports(T* p, typename T::NS_CYCLE_COLLECTION_INNERCLASS* dummy = 0)
 {
   return T::NS_CYCLE_COLLECTION_INNERCLASS::Upcast(p);
 }
 
 // The default implementation of this class template is empty, because it
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -490,20 +490,16 @@ T* DowncastCCParticipant(void *p)
 #define NS_IMPL_CYCLE_COLLECTION_TRACE_END                                     \
       (void)tmp;                                                               \
   }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Helpers for implementing a concrete nsCycleCollectionParticipant 
 ///////////////////////////////////////////////////////////////////////////////
 
-#define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE                               \
-  static const CCParticipantVTable<NS_CYCLE_COLLECTION_INNERCLASS>::Type       \
-      NS_CYCLE_COLLECTION_INNERNAME;
-
 #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)           \
 public:                                                                        \
   static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that,   \
                             void *p, nsCycleCollectionTraversalCallback &cb);  \
   static NS_METHOD_(void) UnmarkIfPurpleImpl(void *s)                          \
   {                                                                            \
     Downcast(static_cast<nsISupports *>(s))->UnmarkIfPurple();                 \
   }                                                                            \
@@ -518,81 +514,94 @@ public:                                 
   template <typename T>                                                        \
   friend nsISupports*                                                          \
   ToSupports(T* p, NS_CYCLE_COLLECTION_INNERCLASS* dummy);
 
 #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                     \
   NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)                 \
   static NS_METHOD UnlinkImpl(void *p);
 
+#define NS_PARTICIPANT_AS(type, participant)                                   \
+  const_cast<type*>(reinterpret_cast<const type*>(participant))
+
+#define NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                 \
+  static nsXPCOMCycleCollectionParticipant* GetParticipant()                   \
+  {                                                                            \
+    static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>    \
+      ::Type p = {                                                             \
+        NS_IMPL_CYCLE_COLLECTION_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) \
+      };                                                                       \
+    return NS_PARTICIPANT_AS(nsXPCOMCycleCollectionParticipant, &p);           \
+  }
+
 #define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base)                \
 class NS_CYCLE_COLLECTION_INNERCLASS                                           \
  : public nsXPCOMCycleCollectionParticipant                                    \
 {                                                                              \
   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                           \
-};                                                                             \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_CLASS(_class)                                 \
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _class)
 
 // Cycle collector helper for ambiguous classes that can sometimes be skipped.
 #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _base)        \
 class NS_CYCLE_COLLECTION_INNERCLASS                                             \
  : public nsXPCOMCycleCollectionParticipant                                      \
 {                                                                                \
   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                             \
   static const bool isSkippable = true;                                          \
   static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed);           \
   static NS_METHOD_(bool) CanSkipInCCImpl(void *p);                              \
   static NS_METHOD_(bool) CanSkipThisImpl(void *p);                              \
-};                                                                               \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(_class)                       \
         NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _class)
 
 #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base)  \
 class NS_CYCLE_COLLECTION_INNERCLASS                                           \
  : public nsXPCOMCycleCollectionParticipant                                    \
 {                                                                              \
   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                           \
   static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
-};                                                                             \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base)   \
 class NS_CYCLE_COLLECTION_INNERCLASS                                                      \
  : public nsXPCOMCycleCollectionParticipant                                               \
 {                                                                                         \
   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                                      \
   static const bool isSkippable = true;                                                   \
   static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure);            \
   static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed);                    \
   static NS_METHOD_(bool) CanSkipInCCImpl(void *p);                                       \
   static NS_METHOD_(bool) CanSkipThisImpl(void *p);                                       \
-};                                                                                        \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                        \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(_class)  \
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
 
 #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(_class,      \
                                                                          _base_class) \
 class NS_CYCLE_COLLECTION_INNERCLASS                                                  \
  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                                  \
 {                                                                                     \
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)                  \
   static const bool isSkippable = true;                                               \
   static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure);        \
   static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed);                \
   static NS_METHOD_(bool) CanSkipInCCImpl(void *p);                                   \
   static NS_METHOD_(bool) CanSkipThisImpl(void *p);                                   \
-};                                                                                    \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class)  \
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
 
 #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class,        \
                                                                 _base_class)   \
 public:                                                                        \
   static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that,   \
@@ -608,38 +617,38 @@ public:                                 
   static NS_METHOD UnlinkImpl(void *p);
 
 #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class)          \
 class NS_CYCLE_COLLECTION_INNERCLASS                                           \
  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
 {                                                                              \
 public:                                                                        \
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)           \
-};                                                                             \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class,             \
                                                            _base_class)        \
 class NS_CYCLE_COLLECTION_INNERCLASS                                           \
  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
 {                                                                              \
 public:                                                                        \
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
-};                                                                             \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(_class,         \
                                                                _base_class)    \
 class NS_CYCLE_COLLECTION_INNERCLASS                                           \
  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
 {                                                                              \
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)           \
   static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
-};                                                                             \
-NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+  NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
+};
 
 /**
  * This implements a stub UnmarkIfPurple function for classes that want to be
  * traversed but whose AddRef/Release functions don't add/remove them to/from
  * the purple buffer. If you're just using NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  * then you don't need this.
  */
 #define NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(_class)                    \
@@ -691,38 +700,28 @@ struct Skippable
 
 #define NS_IMPL_CYCLE_COLLECTION_VTABLE(_class)                                \
   NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(_class)
 
 
 // Cycle collector participant implementations.
 
 // A native class is non-nsISupports and uses nsCycleCollectingAutoRefCnt.
-#define NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class)                          \
-  const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>             \
-    ::Type _class::NS_CYCLE_COLLECTION_INNERNAME =                             \
-  { NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
+#define NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class)
 
 // For native classes containing JS pointers.
-#define NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class)            \
-  const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>             \
-    ::Type _class::NS_CYCLE_COLLECTION_INNERNAME =                             \
-  { NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
+#define NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class)
 
 // A legacy native class is non-nsISupports, but does not use
 // nsCycleCollectingAutoRefCnt. This should be avoided because it can
 // cause leaks.
-#define NS_IMPL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class)                   \
-  NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class)
+#define NS_IMPL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class)
 
 // For nsISupports classes.
-#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                 \
-  const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>             \
-    ::Type _class::NS_CYCLE_COLLECTION_INNERNAME =                             \
-  { NS_IMPL_CYCLE_COLLECTION_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
+#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class)
 
 
 // Cycle collector participant declarations.
 
 #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                     \
   public:                                                                      \
     static NS_METHOD RootImpl(void *n);                                        \
     static NS_METHOD UnlinkImpl(void *n);                                      \
@@ -742,38 +741,62 @@ struct Skippable
     static NS_METHOD_(void) UnmarkIfPurpleImpl(void *p) {}
 
 #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class)                          \
   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
    : public nsCycleCollectionParticipant                                       \
   {                                                                            \
      NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                        \
      NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class)                  \
-  };                                                                           \
-  NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+     static nsCycleCollectionParticipant* GetParticipant()                     \
+     {                                                                         \
+        static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
+        ::Type p = {                                                          \
+           NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(                             \
+              NS_CYCLE_COLLECTION_CLASSNAME(_class))                           \
+        };                                                                     \
+        return NS_PARTICIPANT_AS(nsCycleCollectionParticipant, &p);            \
+    }                                                                          \
+  };
 
 #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class)            \
   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
    : public nsScriptObjectTracer                                               \
   {                                                                            \
     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                         \
     NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class)                   \
     static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb,               \
                                       void *closure);                          \
-  };                                                                           \
-  NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+    static nsScriptObjectTracer* GetParticipant()                              \
+    {                                                                          \
+      static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>  \
+        ::Type participant = {                                                 \
+          NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(                \
+            NS_CYCLE_COLLECTION_CLASSNAME(_class))                             \
+        };                                                                     \
+      return NS_PARTICIPANT_AS(nsScriptObjectTracer, &participant);            \
+    }                                  \
+  };
 
 #define NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class)                   \
   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
    : public nsCycleCollectionParticipant                                       \
   {                                                                            \
      NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                        \
      NS_DECL_CYCLE_COLLECTION_STUB_UNMARK_IF_PURPLE(_class)                    \
-  };                                                                           \
-  NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
+    static nsCycleCollectionParticipant* GetParticipant()                      \
+    {                                                                          \
+      static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>  \
+        ::Type p = {                                                           \
+          NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(                              \
+              NS_CYCLE_COLLECTION_CLASSNAME(_class))                           \
+        };                                                                     \
+      return NS_PARTICIPANT_AS(nsCycleCollectionParticipant, &p);              \
+    }                                                                          \
+  };
 
 #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function)           \
   NS_METHOD                                                                    \
   NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootImpl(void *p)                     \
   {                                                                            \
     _class *tmp = static_cast<_class*>(p);                                     \
     tmp->_root_function();                                                     \
     return NS_OK;                                                              \
--- a/xpcom/glue/nsISupportsImpl.h
+++ b/xpcom/glue/nsISupportsImpl.h
@@ -334,17 +334,17 @@ public:
     NS_LOG_ADDREF(this, count, #_class, sizeof(*this));                       \
     return count;
 
 #define NS_IMPL_CC_NATIVE_RELEASE_BODY(_class)                                \
     NS_PRECONDITION(0 != mRefCnt, "dup release");                             \
     NS_ASSERT_OWNINGTHREAD_AND_NOT_CCTHREAD(_class);                          \
     nsrefcnt count =                                                          \
       mRefCnt.decr(static_cast<void*>(this),                                  \
-                   _class::NS_CYCLE_COLLECTION_INNERNAME.GetParticipant());   \
+                   _class::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant());   \
     NS_LOG_RELEASE(this, count, #_class);                                     \
     if (count == 0) {                                                         \
       NS_ASSERT_OWNINGTHREAD(_class);                                         \
       mRefCnt.stabilizeForDeletion();                                         \
       delete this;                                                            \
       return 0;                                                               \
     }                                                                         \
     return count;