Bug 1302036 - DOM changes to conform to new JS engine API for cloning. r=baku, a=gchang
authorLars T Hansen <lhansen@mozilla.com>
Mon, 24 Oct 2016 15:14:45 +0200
changeset 340833 c683b0d41a52ffab980165b79b9c82590001354b
parent 340832 ba77b4564e33a75bf44127265e1a8e0cd67b8429
child 340834 1fbcdcbb08b76fab36a3a0198618fa5a00da4f51
push id10224
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:34:03 +0000
treeherdermozilla-aurora@c683b0d41a52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, gchang
bugs1302036
milestone51.0a2
Bug 1302036 - DOM changes to conform to new JS engine API for cloning. r=baku, a=gchang
dom/base/StructuredCloneHolder.cpp
dom/base/StructuredCloneHolder.h
dom/base/nsGlobalWindow.cpp
dom/indexedDB/ActorsParent.cpp
dom/ipc/StructuredCloneData.cpp
dom/messagechannel/MessagePort.cpp
dom/workers/ServiceWorkerClient.cpp
dom/workers/WorkerPrivate.cpp
dom/xhr/XMLHttpRequestWorker.cpp
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -170,30 +170,34 @@ StructuredCloneHolderBase::Clear()
 
   mBuffer = nullptr;
 }
 
 bool
 StructuredCloneHolderBase::Write(JSContext* aCx,
                                  JS::Handle<JS::Value> aValue)
 {
-  return Write(aCx, aValue, JS::UndefinedHandleValue);
+  return Write(aCx, aValue, JS::UndefinedHandleValue,
+               JS::CloneDataPolicy().denySharedArrayBuffer());
 }
 
 bool
 StructuredCloneHolderBase::Write(JSContext* aCx,
                                  JS::Handle<JS::Value> aValue,
-                                 JS::Handle<JS::Value> aTransfer)
+                                 JS::Handle<JS::Value> aTransfer,
+                                 JS::CloneDataPolicy cloneDataPolicy)
 {
   MOZ_ASSERT(!mBuffer, "Double Write is not allowed");
   MOZ_ASSERT(!mClearCalled, "This method cannot be called after Clear.");
 
   mBuffer = MakeUnique<JSAutoStructuredCloneBuffer>(mStructuredCloneScope, &StructuredCloneHolder::sCallbacks, this);
 
-  if (!mBuffer->write(aCx, aValue, aTransfer, &StructuredCloneHolder::sCallbacks, this)) {
+  if (!mBuffer->write(aCx, aValue, aTransfer, cloneDataPolicy,
+                      &StructuredCloneHolder::sCallbacks, this))
+  {
     mBuffer = nullptr;
     return false;
   }
 
   return true;
 }
 
 bool
@@ -260,29 +264,31 @@ StructuredCloneHolder::~StructuredCloneH
   MOZ_ASSERT(mTransferredPorts.IsEmpty());
 }
 
 void
 StructuredCloneHolder::Write(JSContext* aCx,
                              JS::Handle<JS::Value> aValue,
                              ErrorResult& aRv)
 {
-  Write(aCx, aValue, JS::UndefinedHandleValue, aRv);
+  Write(aCx, aValue, JS::UndefinedHandleValue,
+        JS::CloneDataPolicy().denySharedArrayBuffer(), aRv);
 }
 
 void
 StructuredCloneHolder::Write(JSContext* aCx,
                              JS::Handle<JS::Value> aValue,
                              JS::Handle<JS::Value> aTransfer,
+                             JS::CloneDataPolicy cloneDataPolicy,
                              ErrorResult& aRv)
 {
   MOZ_ASSERT_IF(mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread,
                 mCreationThread == NS_GetCurrentThread());
 
-  if (!StructuredCloneHolderBase::Write(aCx, aValue, aTransfer)) {
+  if (!StructuredCloneHolderBase::Write(aCx, aValue, aTransfer, cloneDataPolicy)) {
     aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
     return;
   }
 }
 
 void
 StructuredCloneHolder::Read(nsISupports* aParent,
                             JSContext* aCx,
--- a/dom/base/StructuredCloneHolder.h
+++ b/dom/base/StructuredCloneHolder.h
@@ -84,20 +84,22 @@ public:
 
   // These methods are what you should use to read/write data.
 
   // Execute the serialization of aValue using the Structured Clone Algorithm.
   // The data can read back using Read().
   bool Write(JSContext* aCx,
              JS::Handle<JS::Value> aValue);
 
-  // Like Write() but it supports the transferring of objects.
+  // Like Write() but it supports the transferring of objects and handling
+  // of cloning policy.
   bool Write(JSContext* aCx,
              JS::Handle<JS::Value> aValue,
-             JS::Handle<JS::Value> aTransfer);
+             JS::Handle<JS::Value> aTransfer,
+             JS::CloneDataPolicy cloneDataPolicy);
 
   // If Write() has been called, this method retrieves data and stores it into
   // aValue.
   bool Read(JSContext* aCx,
             JS::MutableHandle<JS::Value> aValue);
 
   bool HasData() const
   {
@@ -158,16 +160,17 @@ public:
 
   void Write(JSContext* aCx,
              JS::Handle<JS::Value> aValue,
              ErrorResult &aRv);
 
   void Write(JSContext* aCx,
              JS::Handle<JS::Value> aValue,
              JS::Handle<JS::Value> aTransfer,
+             JS::CloneDataPolicy cloneDataPolicy,
              ErrorResult &aRv);
 
   void Read(nsISupports* aParent,
             JSContext* aCx,
             JS::MutableHandle<JS::Value> aValue,
             ErrorResult &aRv);
 
   // Call this method to know if this object is keeping some DOM object alive.
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8360,17 +8360,17 @@ nsGlobalWindow::PostMessageMozOuter(JSCo
                          callerInnerWin
                          ? callerInnerWin->GetDoc()
                          : nullptr,
                          nsContentUtils::IsCallerChrome());
 
   JS::Rooted<JS::Value> message(aCx, aMessage);
   JS::Rooted<JS::Value> transfer(aCx, aTransfer);
 
-  event->Write(aCx, message, transfer, aError);
+  event->Write(aCx, message, transfer, JS::CloneDataPolicy(), aError);
   if (NS_WARN_IF(aError.Failed())) {
     return;
   }
 
   aError = NS_DispatchToCurrentThread(event);
 }
 
 void
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -144,21 +144,21 @@ class TransactionDatabaseOperationBase;
 class VersionChangeTransaction;
 
 /*******************************************************************************
  * Constants
  ******************************************************************************/
 
 // If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
 // schema version.
-static_assert(JS_STRUCTURED_CLONE_VERSION == 7,
+static_assert(JS_STRUCTURED_CLONE_VERSION == 8,
               "Need to update the major schema version.");
 
 // Major schema version. Bump for almost everything.
-const uint32_t kMajorSchemaVersion = 24;
+const uint32_t kMajorSchemaVersion = 25;
 
 // Minor schema version. Should almost always be 0 (maybe bump on release
 // branches if we have to).
 const uint32_t kMinorSchemaVersion = 0;
 
 // The schema version we store in the SQLite database is a (signed) 32-bit
 // integer. The major version is left-shifted 4 bits so the max value is
 // 0xFFFFFFF. The minor version occupies the lower 4 bits and its max is 0xF.
@@ -4110,16 +4110,29 @@ UpgradeSchemaFrom23_0To24_0(mozIStorageC
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult
+UpgradeSchemaFrom24_0To25_0(mozIStorageConnection* aConnection)
+{
+  // The only change between 24 and 25 was a different structured clone format,
+  // but it's backwards-compatible.
+  nsresult rv = aConnection->SetSchemaVersion(MakeSchemaVersion(25, 0));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return NS_OK;
+}
+
+nsresult
 GetDatabaseFileURL(nsIFile* aDatabaseFile,
                    PersistenceType aPersistenceType,
                    const nsACString& aGroup,
                    const nsACString& aOrigin,
                    uint32_t aTelemetryId,
                    nsIFileURL** aResult)
 {
   MOZ_ASSERT(aDatabaseFile);
@@ -4615,17 +4628,17 @@ CreateStorageConnection(nsIFile* aDBFile
       }
 
       rv = stmt->Execute();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else  {
       // This logic needs to change next time we change the schema!
-      static_assert(kSQLiteSchemaVersion == int32_t((24 << 4) + 0),
+      static_assert(kSQLiteSchemaVersion == int32_t((25 << 4) + 0),
                     "Upgrade function needed due to schema version increase.");
 
       while (schemaVersion != kSQLiteSchemaVersion) {
         if (schemaVersion == 4) {
           rv = UpgradeSchemaFrom4To5(connection);
         } else if (schemaVersion == 5) {
           rv = UpgradeSchemaFrom5To6(connection);
         } else if (schemaVersion == 6) {
@@ -4661,16 +4674,18 @@ CreateStorageConnection(nsIFile* aDBFile
         } else if (schemaVersion == MakeSchemaVersion(20, 0)) {
           rv = UpgradeSchemaFrom20_0To21_0(connection);
         } else if (schemaVersion == MakeSchemaVersion(21, 0)) {
           rv = UpgradeSchemaFrom21_0To22_0(connection);
         } else if (schemaVersion == MakeSchemaVersion(22, 0)) {
           rv = UpgradeSchemaFrom22_0To23_0(connection, aOrigin);
         } else if (schemaVersion == MakeSchemaVersion(23, 0)) {
           rv = UpgradeSchemaFrom23_0To24_0(connection);
+        } else if (schemaVersion == MakeSchemaVersion(24, 0)) {
+          rv = UpgradeSchemaFrom24_0To25_0(connection);
         } else {
           IDB_WARNING("Unable to open IndexedDB database, no upgrade path is "
                       "available!");
           return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
         }
 
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
--- a/dom/ipc/StructuredCloneData.cpp
+++ b/dom/ipc/StructuredCloneData.cpp
@@ -76,17 +76,18 @@ StructuredCloneData::Write(JSContext* aC
 void
 StructuredCloneData::Write(JSContext* aCx,
                            JS::Handle<JS::Value> aValue,
                            JS::Handle<JS::Value> aTransfer,
                            ErrorResult &aRv)
 {
   MOZ_ASSERT(!mInitialized);
 
-  StructuredCloneHolder::Write(aCx, aValue, aTransfer, aRv);
+  StructuredCloneHolder::Write(aCx, aValue, aTransfer,
+                               JS::CloneDataPolicy().denySharedArrayBuffer(), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   JSStructuredCloneData data;
   mBuffer->abandon();
   mBuffer->steal(&data);
   mBuffer = nullptr;
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -439,17 +439,18 @@ MessagePort::PostMessage(JSContext* aCx,
   bool isTimelineRecording = timelines && !timelines->IsEmpty();
 
   if (isTimelineRecording) {
     start = MakeUnique<MessagePortTimelineMarker>(
       ProfileTimelineMessagePortOperationType::SerializeData,
       MarkerTracingType::START);
   }
 
-  data->Write(aCx, aMessage, transferable, aRv);
+  data->Write(aCx, aMessage, transferable,
+              JS::CloneDataPolicy().denySharedArrayBuffer(), aRv);
 
   if (isTimelineRecording) {
     end = MakeUnique<MessagePortTimelineMarker>(
       ProfileTimelineMessagePortOperationType::SerializeData,
       MarkerTracingType::END);
     timelines->AddMarkerForAllObservedDocShells(start);
     timelines->AddMarkerForAllObservedDocShells(end);
   }
--- a/dom/workers/ServiceWorkerClient.cpp
+++ b/dom/workers/ServiceWorkerClient.cpp
@@ -221,17 +221,18 @@ ServiceWorkerClient::PostMessage(JSConte
     }
 
     transferable.setObject(*array);
   }
 
   RefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
     new ServiceWorkerClientPostMessageRunnable(mWindowId);
 
-  runnable->Write(aCx, aMessage, transferable, aRv);
+  runnable->Write(aCx, aMessage, transferable, JS::CloneDataPolicy().denySharedArrayBuffer(),
+                  aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   aRv = workerPrivate->DispatchToMainThread(runnable.forget());
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2843,17 +2843,17 @@ WorkerPrivateParent<Derived>::PostMessag
 
   if (isTimelineRecording) {
     start = MakeUnique<WorkerTimelineMarker>(NS_IsMainThread()
       ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
       : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
       MarkerTracingType::START);
   }
 
-  runnable->Write(aCx, aMessage, transferable, aRv);
+  runnable->Write(aCx, aMessage, transferable, JS::CloneDataPolicy(), aRv);
 
   if (isTimelineRecording) {
     end = MakeUnique<WorkerTimelineMarker>(NS_IsMainThread()
       ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
       : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
       MarkerTracingType::END);
     timelines->AddMarkerForAllObservedDocShells(start);
     timelines->AddMarkerForAllObservedDocShells(end);
@@ -5560,17 +5560,17 @@ WorkerPrivate::PostMessageToParentIntern
 
   if (isTimelineRecording) {
     start = MakeUnique<WorkerTimelineMarker>(NS_IsMainThread()
       ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
       : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
       MarkerTracingType::START);
   }
 
-  runnable->Write(aCx, aMessage, transferable, aRv);
+  runnable->Write(aCx, aMessage, transferable, JS::CloneDataPolicy(), aRv);
 
   if (isTimelineRecording) {
     end = MakeUnique<WorkerTimelineMarker>(NS_IsMainThread()
       ? ProfileTimelineWorkerOperationType::SerializeDataOnMainThread
       : ProfileTimelineWorkerOperationType::SerializeDataOffMainThread,
       MarkerTracingType::END);
     timelines->AddMarkerForAllObservedDocShells(start);
     timelines->AddMarkerForAllObservedDocShells(end);
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -1170,17 +1170,17 @@ EventRunnable::PreDispatch(WorkerPrivate
             } else {
               mResponseResult = NS_ERROR_OUT_OF_MEMORY;
               doClone = false;
             }
           }
         }
 
         if (doClone) {
-          Write(cx, response, transferable, rv);
+          Write(cx, response, transferable, JS::CloneDataPolicy(), rv);
           if (NS_WARN_IF(rv.Failed())) {
             NS_WARNING("Failed to clone response!");
             mResponseResult = rv.StealNSResult();
             mProxy->mArrayBufferResponseWasTransferred = false;
           }
         }
       }
     }