Bug 1043853 - Share the code for structured cloning of ImageData objects across main-thread and workers implementations; r=jst
☠☠ backed out by 2be279648457 ☠ ☠
authorMs2ger <ms2ger@gmail.com>
Fri, 01 Aug 2014 22:47:47 +0200
changeset 197551 a668ab2d8dd36f35ce7b9c7f814550322ee40f0b
parent 197550 221ded3982a7b6278d850b04b13d28a81940df9d
child 197552 2be279648457ea6a6eb4eb663910a58de9936969
push id27249
push userryanvm@gmail.com
push dateMon, 04 Aug 2014 20:14:35 +0000
treeherderautoland@7f81be7db528 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs1043853
milestone34.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 1043853 - Share the code for structured cloning of ImageData objects across main-thread and workers implementations; r=jst
dom/base/nsJSEnvironment.cpp
dom/bindings/StructuredClone.cpp
dom/bindings/StructuredClone.h
dom/bindings/moz.build
dom/workers/WorkerPrivate.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -49,20 +49,21 @@
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "prmem.h"
 #include "WrapperFactory.h"
 #include "nsGlobalWindow.h"
 #include "nsScriptNameSpaceManager.h"
 #include "StructuredCloneTags.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/dom/CryptoKey.h"
 #include "mozilla/dom/ErrorEvent.h"
+#include "mozilla/dom/ImageDataBinding.h"
 #include "mozilla/dom/ImageData.h"
-#include "mozilla/dom/CryptoKey.h"
-#include "mozilla/dom/ImageDataBinding.h"
+#include "mozilla/dom/StructuredClone.h"
 #include "mozilla/dom/SubtleCryptoBinding.h"
 #include "nsAXPCNativeCallContext.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 
 #include "nsJSPrincipals.h"
 
 #ifdef XP_MACOSX
 // AssertMacros.h defines 'check' and conflicts with AccessCheck.h
@@ -2806,35 +2807,17 @@ SetIncrementalCCPrefChangedCallback(cons
 JSObject*
 NS_DOMReadStructuredClone(JSContext* cx,
                           JSStructuredCloneReader* reader,
                           uint32_t tag,
                           uint32_t data,
                           void* closure)
 {
   if (tag == SCTAG_DOM_IMAGEDATA) {
-    // Read the information out of the stream.
-    uint32_t width, height;
-    JS::Rooted<JS::Value> dataArray(cx);
-    if (!JS_ReadUint32Pair(reader, &width, &height) ||
-        !JS_ReadTypedArray(reader, &dataArray)) {
-      return nullptr;
-    }
-    MOZ_ASSERT(dataArray.isObject());
-
-    // Protect the result from a moving GC in ~nsRefPtr.
-    JS::Rooted<JSObject*> result(cx);
-    {
-      // Construct the ImageData.
-      nsRefPtr<ImageData> imageData = new ImageData(width, height,
-                                                    dataArray.toObject());
-      // Wrap it in a JS::Value.
-      result = imageData->WrapObject(cx);
-    }
-    return result;
+    return ReadStructuredCloneImageData(cx, reader);
   } else if (tag == SCTAG_DOM_WEBCRYPTO_KEY) {
     nsIGlobalObject *global = xpc::GetNativeForGlobal(JS::CurrentGlobalOrNull(cx));
     if (!global) {
       return nullptr;
     }
 
     // Prevent the return value from being trashed by a GC during ~nsRefPtr.
     JS::Rooted<JSObject*> result(cx);
@@ -2858,27 +2841,17 @@ bool
 NS_DOMWriteStructuredClone(JSContext* cx,
                            JSStructuredCloneWriter* writer,
                            JS::Handle<JSObject*> obj,
                            void *closure)
 {
   // Handle ImageData cloning
   ImageData* imageData;
   if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, obj, imageData))) {
-    // Prepare the ImageData internals.
-    uint32_t width = imageData->Width();
-    uint32_t height = imageData->Height();
-    JS::Rooted<JSObject*> dataArray(cx, imageData->GetDataObject());
-
-    // Write the internals to the stream.
-    JSAutoCompartment ac(cx, dataArray);
-    JS::Rooted<JS::Value> arrayValue(cx, JS::ObjectValue(*dataArray));
-    return JS_WriteUint32Pair(writer, SCTAG_DOM_IMAGEDATA, 0) &&
-           JS_WriteUint32Pair(writer, width, height) &&
-           JS_WriteTypedArray(writer, arrayValue);
+    return WriteStructuredCloneImageData(cx, writer, imageData);
   }
 
   // Handle Key cloning
   CryptoKey* key;
   if (NS_SUCCEEDED(UNWRAP_OBJECT(CryptoKey, obj, key))) {
     return JS_WriteUint32Pair(writer, SCTAG_DOM_WEBCRYPTO_KEY, 0) &&
            key->WriteStructuredClone(writer);
   }
new file mode 100644
--- /dev/null
+++ b/dom/bindings/StructuredClone.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/StructuredClone.h"
+
+#include "js/StructuredClone.h"
+#include "mozilla/dom/ImageData.h"
+#include "mozilla/dom/StructuredCloneTags.h"
+
+namespace mozilla {
+namespace dom {
+
+JSObject*
+ReadStructuredCloneImageData(JSContext* aCx, JSStructuredCloneReader* aReader)
+{
+  // Read the information out of the stream.
+  uint32_t width, height;
+  JS::Rooted<JS::Value> dataArray(aCx);
+  if (!JS_ReadUint32Pair(aReader, &width, &height) ||
+      !JS_ReadTypedArray(aReader, &dataArray)) {
+    return nullptr;
+  }
+  MOZ_ASSERT(dataArray.isObject());
+
+  // Protect the result from a moving GC in ~nsRefPtr.
+  JS::Rooted<JSObject*> result(aCx);
+  {
+    // Construct the ImageData.
+    nsRefPtr<ImageData> imageData = new ImageData(width, height,
+                                                  dataArray.toObject());
+    // Wrap it in a JS::Value.
+    result = imageData->WrapObject(aCx);
+  }
+  return result;
+}
+
+bool
+WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+                              ImageData* aImageData)
+{
+  uint32_t width = aImageData->Width();
+  uint32_t height = aImageData->Height();
+  JS::Rooted<JSObject*> dataArray(aCx, aImageData->GetDataObject());
+
+  JSAutoCompartment ac(aCx, dataArray);
+  JS::Rooted<JS::Value> arrayValue(aCx, JS::ObjectValue(*dataArray));
+  return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
+         JS_WriteUint32Pair(aWriter, width, height) &&
+         JS_WriteTypedArray(aWriter, arrayValue);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/bindings/StructuredClone.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+class JSObject;
+struct JSContext;
+struct JSStructuredCloneReader;
+struct JSStructuredCloneWriter;
+
+namespace mozilla {
+namespace dom {
+
+class ImageData;
+
+JSObject*
+ReadStructuredCloneImageData(JSContext* aCx, JSStructuredCloneReader* aReader);
+
+bool
+WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+                              ImageData* aImageData);
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -25,16 +25,17 @@ EXPORTS.mozilla.dom += [
     'Exceptions.h',
     'JSSlots.h',
     'MozMap.h',
     'NonRefcountedDOMObject.h',
     'Nullable.h',
     'OwningNonNull.h',
     'PrimitiveConversions.h',
     'RootedDictionary.h',
+    'StructuredClone.h',
     'ToJSValue.h',
     'TypedArray.h',
     'UnionMember.h',
 ]
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
@@ -76,16 +77,20 @@ UNIFIED_SOURCES += [
     'CallbackInterface.cpp',
     'CallbackObject.cpp',
     'Date.cpp',
     'DOMJSProxyHandler.cpp',
     'Exceptions.cpp',
     'ToJSValue.cpp',
 ]
 
+SOURCES += [
+    'StructuredClone.cpp',
+]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
     LOCAL_INCLUDES += [
         '/dom/system/gonk',
     ]
 
 FINAL_LIBRARY = 'xul'
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -43,16 +43,17 @@
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/ImageDataBinding.h"
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/MessagePortList.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/StructuredClone.h"
 #include "mozilla/dom/WorkerBinding.h"
 #include "mozilla/Preferences.h"
 #include "nsAlgorithm.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsError.h"
 #include "nsDOMJSUtils.h"
 #include "nsHostObjectProtocolHandler.h"
@@ -347,35 +348,17 @@ struct WorkerStructuredCloneCallbacks
           result = file::CreateBlob(aCx, blob);
         }
         return result;
       }
     }
     // See if the object is an ImageData.
     else if (aTag == SCTAG_DOM_IMAGEDATA) {
       MOZ_ASSERT(!aData);
-
-      // Read the information out of the stream.
-      uint32_t width, height;
-      JS::Rooted<JS::Value> dataArray(aCx);
-      if (!JS_ReadUint32Pair(aReader, &width, &height) ||
-          !JS_ReadTypedArray(aReader, &dataArray))
-      {
-        return nullptr;
-      }
-      MOZ_ASSERT(dataArray.isObject());
-
-      {
-        // Construct the ImageData.
-        nsRefPtr<ImageData> imageData = new ImageData(width, height,
-                                                      dataArray.toObject());
-        // Wrap it in a JS::Value, protected from a moving GC during ~nsRefPtr.
-        result = imageData->WrapObject(aCx);
-      }
-      return result;
+      return ReadStructuredCloneImageData(aCx, aReader);
     }
 
     Error(aCx, 0);
     return nullptr;
   }
 
   static bool
   Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
@@ -413,27 +396,17 @@ struct WorkerStructuredCloneCallbacks
         }
       }
     }
 
     // See if this is an ImageData object.
     {
       ImageData* imageData = nullptr;
       if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) {
-        // Prepare the ImageData internals.
-        uint32_t width = imageData->Width();
-        uint32_t height = imageData->Height();
-        JS::Rooted<JSObject*> dataArray(aCx, imageData->GetDataObject());
-
-        // Write the internals to the stream.
-        JSAutoCompartment ac(aCx, dataArray);
-        JS::Rooted<JS::Value> arrayValue(aCx, JS::ObjectValue(*dataArray));
-        return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
-               JS_WriteUint32Pair(aWriter, width, height) &&
-               JS_WriteTypedArray(aWriter, arrayValue);
+        return WriteStructuredCloneImageData(aCx, aWriter, imageData);
       }
     }
 
     Error(aCx, 0);
     return false;
   }
 
   static void