Bug 1250767 - Add support for hanging servo node data off Gecko nodes. r=heycam,r=bz
authorBobby Holley <bobbyholley@gmail.com>
Tue, 23 Feb 2016 17:28:50 -0800
changeset 321814 7661eb78c9ac833265f6f5b8fa239a1e82f2ed94
parent 321813 ee63c83bf27218fa1381956ecfe66548eae9d1b9
child 321815 a746bcde48332de09d317f6a3219ecefdfa88d28
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, bz
bugs1250767
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1250767 - Add support for hanging servo node data off Gecko nodes. r=heycam,r=bz
dom/base/nsINode.cpp
dom/base/nsINode.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -15,16 +15,17 @@
 #include "mozAutoDocUpdate.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/ServoBindings.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "nsAttrValueOrString.h"
 #include "nsBindingManager.h"
@@ -143,16 +144,22 @@ nsINode::nsSlots::Unlink()
 }
 
 //----------------------------------------------------------------------
 
 nsINode::~nsINode()
 {
   MOZ_ASSERT(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
   MOZ_ASSERT(mSubtreeRoot == this, "Didn't restore state properly?");
+
+#ifdef MOZ_STYLO
+  if (mServoNodeData) {
+    Servo_DropNodeData(mServoNodeData);
+  }
+#endif
 }
 
 void*
 nsINode::GetProperty(uint16_t aCategory, nsIAtom *aPropertyName,
                      nsresult *aStatus) const
 {
   return OwnerDoc()->PropertyTable(aCategory)->GetProperty(this, aPropertyName,
                                                            aStatus);
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -46,16 +46,17 @@ class nsIMutationObserver;
 class nsINode;
 class nsINodeList;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIURI;
 class nsNodeSupportsWeakRefTearoff;
 class nsNodeWeakReference;
 class nsDOMMutationObserver;
+struct ServoNodeData;
 
 namespace mozilla {
 class EventListenerManager;
 namespace dom {
 /**
  * @return true if aChar is what the DOM spec defines as 'space character'.
  * http://dom.spec.whatwg.org/#space-character
  */
@@ -308,24 +309,27 @@ public:
 
   friend class nsNodeUtils;
   friend class nsNodeWeakReference;
   friend class nsNodeSupportsWeakRefTearoff;
   friend class nsAttrAndChildArray;
 
 #ifdef MOZILLA_INTERNAL_API
   explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : mNodeInfo(aNodeInfo),
-    mParent(nullptr),
-    mBoolFlags(0),
-    mNextSibling(nullptr),
-    mPreviousSibling(nullptr),
-    mFirstChild(nullptr),
-    mSubtreeRoot(this),
-    mSlots(nullptr)
+  : mNodeInfo(aNodeInfo)
+  , mParent(nullptr)
+  , mBoolFlags(0)
+  , mNextSibling(nullptr)
+  , mPreviousSibling(nullptr)
+  , mFirstChild(nullptr)
+  , mSubtreeRoot(this)
+  , mSlots(nullptr)
+#ifdef MOZ_STYLO
+  , mServoNodeData(nullptr)
+#endif
   {
   }
 #endif
 
   virtual ~nsINode();
 
   /**
    * Bit-flags to pass (or'ed together) to IsNodeOfType()
@@ -1966,16 +1970,33 @@ public:
   void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener);
 #define TOUCH_EVENT EVENT
 #define DOCUMENT_ONLY_EVENT EVENT
 #include "mozilla/EventNameList.h"
 #undef DOCUMENT_ONLY_EVENT
 #undef TOUCH_EVENT
 #undef EVENT
 
+  ServoNodeData* GetServoNodeData() {
+#ifdef MOZ_STYLO
+    return mServoNodeData;
+#else
+    MOZ_CRASH("Accessing servo node data in non-stylo build");
+#endif
+  }
+
+  void SetServoNodeData(ServoNodeData* aData) {
+#ifdef MOZ_STYLO
+  MOZ_ASSERT(!mServoNodeData);
+  mServoNodeData = aData;
+#else
+    MOZ_CRASH("Setting servo node data in non-stylo build");
+#endif
+  }
+
 protected:
   static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb);
   static void Unlink(nsINode *tmp);
 
   RefPtr<mozilla::dom::NodeInfo> mNodeInfo;
 
   // mParent is an owning ref most of the time, except for the case of document
   // nodes, so it cannot be represented by nsCOMPtr, so mark is as
@@ -2003,16 +2024,21 @@ protected:
     // Pointer to the root of our subtree.  Might be null.
     // This reference is non-owning and safe, since it either points to the
     // object itself, or is reset by ClearSubtreeRootPointer.
     nsINode* MOZ_NON_OWNING_REF mSubtreeRoot;
   };
 
   // Storage for more members that are usually not needed; allocated lazily.
   nsSlots* mSlots;
+
+#ifdef MOZ_STYLO
+  // Layout data managed by Servo.
+  ServoNodeData* mServoNodeData;
+#endif
 };
 
 inline nsIDOMNode* GetAsDOMNode(nsINode* aNode)
 {
   return aNode ? aNode->AsDOMNode() : nullptr;
 }
 
 // Useful inline function for getting a node given an nsIContent and an
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -124,8 +124,19 @@ Gecko_IsUnvisitedLink(RawGeckoElement* a
 }
 
 int
 Gecko_IsRootElement(RawGeckoElement* aElement)
 {
   return aElement->OwnerDoc()->GetRootElement() == aElement;
 }
 
+ServoNodeData*
+Gecko_GetNodeData(RawGeckoNode* aNode)
+{
+  return aNode->GetServoNodeData();
+}
+
+void
+Gecko_SetNodeData(RawGeckoNode* aNode, ServoNodeData* aData)
+{
+  aNode->SetServoNodeData(aData);
+}
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -20,23 +20,26 @@
 #ifdef __cplusplus
 class nsINode;
 typedef nsINode RawGeckoNode;
 namespace mozilla { namespace dom { class Element; } }
 using mozilla::dom::Element;
 typedef mozilla::dom::Element RawGeckoElement;
 class nsIDocument;
 typedef nsIDocument RawGeckoDocument;
+struct ServoNodeData;
 #else
 struct RawGeckoNode;
 typedef struct RawGeckoNode RawGeckoNode;
 struct RawGeckoElement;
 typedef struct RawGeckoElement RawGeckoElement;
 struct RawGeckoDocument;
 typedef struct RawGeckoDocument RawGeckoDocument;
+struct ServoNodeData;
+typedef struct ServoNodeData ServoNodeData;
 #endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // DOM Traversal.
 uint32_t Gecko_ChildrenCount(RawGeckoNode* node);
@@ -56,16 +59,21 @@ RawGeckoElement* Gecko_GetDocumentElemen
 // Selector Matching.
 int Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* element);
 int Gecko_IsLink(RawGeckoElement* element);
 int Gecko_IsTextNode(RawGeckoNode* node);
 int Gecko_IsVisitedLink(RawGeckoElement* element);
 int Gecko_IsUnvisitedLink(RawGeckoElement* element);
 int Gecko_IsRootElement(RawGeckoElement* element);
 
+// Node data.
+ServoNodeData* Gecko_GetNodeData(RawGeckoNode* node);
+void Gecko_SetNodeData(RawGeckoNode* node, ServoNodeData* data);
+void Servo_DropNodeData(ServoNodeData* data);
+
 // Servo API.
 void Servo_RestyleDocument(RawGeckoDocument* aDoc);
 
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
 #endif // mozilla_ServoBindings_h