Bug 1283636 - Use CallbackPreserveColor() less. r=bz
authorAndrew McCreight <continuation@gmail.com>
Wed, 13 Jul 2016 13:28:00 +0200
changeset 305013 347b46d43b8bfbc986529765827c0f46dd50c976
parent 305012 1e5ba0ffc0c2ab38cef339ed8d8adf3d864d1501
child 305014 79f9307c33eaaf2df414d129cbf7a152b0ba6396
push id30450
push usercbook@mozilla.com
push dateFri, 15 Jul 2016 14:15:45 +0000
treeherdermozilla-central@2f9e69c982f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1283636
milestone50.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 1283636 - Use CallbackPreserveColor() less. r=bz Some places call CallbackPreserveColor() because they know the object must have already been marked black. This patch replaces those calls with a new function CallbackKnownNotGray() which documents and dynamically checks this assumption.
dom/bindings/CallbackInterface.cpp
dom/bindings/CallbackObject.h
dom/bindings/Codegen.py
--- a/dom/bindings/CallbackInterface.cpp
+++ b/dom/bindings/CallbackInterface.cpp
@@ -11,17 +11,17 @@
 
 namespace mozilla {
 namespace dom {
 
 bool
 CallbackInterface::GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
                                        JS::MutableHandle<JS::Value> aCallable)
 {
-  if (!JS_GetPropertyById(cx, CallbackPreserveColor(), aPropId, aCallable)) {
+  if (!JS_GetPropertyById(cx, CallbackKnownNotGray(), aPropId, aCallable)) {
     return false;
   }
   if (!aCallable.isObject() ||
       !JS::IsCallable(&aCallable.toObject())) {
     char* propName =
       JS_EncodeString(cx, JS_FORGET_STRING_FLATNESS(JSID_TO_FLAT_STRING(aPropId)));
     nsPrintfCString description("Property '%s'", propName);
     JS_free(cx, propName);
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -114,16 +114,27 @@ public:
    */
   JS::Handle<JSObject*> CallbackPreserveColor() const
   {
     // Calling fromMarkedLocation() is safe because we trace our mCallback, and
     // because the value of mCallback cannot change after if has been set.
     return JS::Handle<JSObject*>::fromMarkedLocation(mCallback.address());
   }
 
+  /*
+   * If the callback is known to be non-gray, then this method can be
+   * used instead of Callback() to avoid the overhead of
+   * ExposeObjectToActiveJS().
+   */
+  JS::Handle<JSObject*> CallbackKnownNotGray() const
+  {
+    MOZ_ASSERT(!JS::ObjectIsMarkedGray(mCallback.get()));
+    return CallbackPreserveColor();
+  }
+
   nsIGlobalObject* IncumbentGlobalOrNull() const
   {
     return mIncumbentGlobal;
   }
 
   enum ExceptionHandling {
     // Report any exception and don't throw it to the caller code.
     eReportExceptions,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -15042,22 +15042,22 @@ class FakeMember():
         # Claim to be a [NewObject] so we can avoid the "return a raw pointer"
         # comments CGNativeMember codegen would otherwise stick in.
         if name == "NewObject":
             return True
         return None
 
 
 class CallbackMember(CGNativeMember):
-    # XXXbz It's OK to use CallbackPreserveColor for wrapScope because
+    # XXXbz It's OK to use CallbackKnownNotGray for wrapScope because
     # CallSetup already handled the unmark-gray bits for us. we don't have
     # anything better to use for 'obj', really...
     def __init__(self, sig, name, descriptorProvider, needThisHandling,
                  rethrowContentException=False, typedArraysAreStructs=False,
-                 wrapScope='CallbackPreserveColor()'):
+                 wrapScope='CallbackKnownNotGray()'):
         """
         needThisHandling is True if we need to be able to accept a specified
         thisObj, False otherwise.
         """
         assert not rethrowContentException or not needThisHandling
 
         self.retvalType = sig[0]
         self.originalSig = sig
@@ -15498,17 +15498,17 @@ class CallbackSetter(CallbackAccessor):
         return ""
 
     def getCall(self):
         return fill(
             """
             MOZ_ASSERT(argv.length() == 1);
             ${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
             if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
-                !JS_SetPropertyById(cx, CallbackPreserveColor(), atomsCache->${attrAtomName}, argv[0])) {
+                !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->${attrAtomName}, argv[0])) {
               aRv.Throw(NS_ERROR_UNEXPECTED);
               return${errorReturn};
             }
             """,
             atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
             attrAtomName=CGDictionary.makeIdName(self.descriptorProvider.binaryNameFor(self.attrName)),
             errorReturn=self.getDefaultRetval())