Backed out 5 changesets (bug 1149987) for mochitest crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 08 Apr 2015 11:49:49 -0400
changeset 238182 7fbf03927859971b3cf07c7663cd4c000eaadb73
parent 238181 55524bdeb708cca0f7b128fbe3e1e58cbece899d
child 238183 8911c111a6adbd5dd6f784a63763864bafa18798
push id28557
push userkwierso@gmail.com
push dateThu, 09 Apr 2015 00:04:16 +0000
treeherdermozilla-central@9a29065e2311 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1149987
milestone40.0a1
backs outb62e371d61898c241efec2cb9fe7f11d0b86395d
daa762fca8e68d966180ef062412224bf782c69f
bdb64d5befa55cb4f57673dadaf8e58435604032
693901a4bcde177154392671ccbae2070697ea36
e7c41c8653c43605976eb5b1579303590ec35414
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
Backed out 5 changesets (bug 1149987) for mochitest crashes. Backed out changeset b62e371d6189 (bug 1149987) Backed out changeset daa762fca8e6 (bug 1149987) Backed out changeset bdb64d5befa5 (bug 1149987) Backed out changeset 693901a4bcde (bug 1149987) Backed out changeset e7c41c8653c4 (bug 1149987) CLOSED TREE
dom/bindings/BindingUtils.cpp
dom/bindings/ErrorIPCUtils.h
dom/bindings/ErrorResult.h
dom/bindings/Errors.msg
dom/bindings/moz.build
dom/cache/Cache.cpp
dom/cache/Cache.h
dom/cache/CacheChild.cpp
dom/cache/CacheChild.h
dom/cache/CacheParent.cpp
dom/cache/CacheParent.h
dom/cache/DBSchema.cpp
dom/cache/FetchPut.cpp
dom/cache/FetchPut.h
dom/cache/PCache.ipdl
dom/cache/TypeUtils.cpp
dom/cache/test/mochitest/test_cache_match_vary.js
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -8,17 +8,16 @@
 
 #include <algorithm>
 #include <stdarg.h>
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/unused.h"
 
 #include "AccessCheck.h"
 #include "jsfriendapi.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDOMGlobalPropertyInitializer.h"
 #include "nsIPermissionManager.h"
@@ -42,17 +41,16 @@
 #include "mozilla/dom/HTMLSharedObjectElement.h"
 #include "mozilla/dom/HTMLEmbedElementBinding.h"
 #include "mozilla/dom/HTMLAppletElementBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "WorkerPrivate.h"
 #include "nsDOMClassInfo.h"
-#include "ipc/ErrorIPCUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 JSErrorFormatString ErrorFormatString[] = {
 #define MSG_DEF(_name, _argc, _exn, _str) \
   { _str, _argc, _exn },
 #include "mozilla/dom/Errors.msg"
@@ -147,41 +145,16 @@ ErrorResult::ThrowErrorWithMessage(va_li
   argCount = std::min<uint16_t>(argCount, 10);
   while (argCount--) {
     message->mArgs.AppendElement(*va_arg(ap, nsString*));
   }
   mMessage = message;
 }
 
 void
-ErrorResult::SerializeMessage(IPC::Message* aMsg) const
-{
-  using namespace IPC;
-  MOZ_ASSERT(mMessage);
-  WriteParam(aMsg, mMessage->mArgs);
-  WriteParam(aMsg, mMessage->mErrorNumber);
-}
-
-bool
-ErrorResult::DeserializeMessage(const IPC::Message* aMsg, void** aIter)
-{
-  using namespace IPC;
-  nsAutoPtr<Message> readMessage(new Message());
-  if (!ReadParam(aMsg, aIter, &readMessage->mArgs) ||
-      !ReadParam(aMsg, aIter, &readMessage->mErrorNumber)) {
-    return false;
-  }
-  if (mMessage) {
-    delete mMessage;
-  }
-  mMessage = readMessage.forget();
-  return true;
-}
-
-void
 ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
 {
   va_list ap;
   va_start(ap, errorNumber);
   ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_TYPE_ERR);
   va_end(ap);
 }
 
@@ -323,47 +296,16 @@ ErrorResult::ReportNotEnoughArgsError(JS
                                       const char* memberName)
 {
   MOZ_ASSERT(ErrorCode() == NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
   nsPrintfCString errorMessage("%s.%s", ifaceName, memberName);
   ThrowErrorMessage(cx, dom::MSG_MISSING_ARGUMENTS, errorMessage.get());
 }
 
-ErrorResult&
-ErrorResult::operator=(ErrorResult&& aRHS)
-{
-#ifdef DEBUG
-  mMightHaveUnreportedJSException = aRHS.mMightHaveUnreportedJSException;
-  aRHS.mMightHaveUnreportedJSException = false;
-#endif
-  if (aRHS.IsErrorWithMessage()) {
-    mMessage = aRHS.mMessage;
-    aRHS.mMessage = nullptr;
-  } else if (aRHS.IsJSException()) {
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-    MOZ_ASSERT(cx);
-    mJSException.setUndefined();
-    if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
-      MOZ_CRASH("Could not root mJSException, we're about to OOM");
-    }
-    mJSException = aRHS.mJSException;
-    aRHS.mJSException.setUndefined();
-    js::RemoveRawValueRoot(cx, &aRHS.mJSException);
-  } else {
-    // Null out the union on both sides for hygiene purposes.
-    mMessage = aRHS.mMessage = nullptr;
-  }
-  // Note: It's important to do this last, since this affects the condition
-  // checks above!
-  mResult = aRHS.mResult;
-  aRHS.mResult = NS_OK;
-  return *this;
-}
-
 namespace dom {
 
 bool
 DefineConstants(JSContext* cx, JS::Handle<JSObject*> obj,
                 const ConstantSpec* cs)
 {
   JS::Rooted<JS::Value> value(cx);
   for (; cs->name; ++cs) {
deleted file mode 100644
--- a/dom/bindings/ErrorIPCUtils.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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 "ipc/IPCMessageUtils.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/Move.h"
-
-#ifndef IPC_ErrorIPCUtils_h
-#define IPC_ErrorIPCUtils_h
-
-namespace IPC {
-
-template<>
-struct ParamTraits<mozilla::dom::ErrNum> :
-  public ContiguousEnumSerializer<mozilla::dom::ErrNum,
-                                  mozilla::dom::ErrNum(0),
-                                  mozilla::dom::ErrNum(mozilla::dom::Err_Limit)> {};
-
-template<>
-struct ParamTraits<mozilla::ErrorResult>
-{
-  typedef mozilla::ErrorResult paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    // It should be the case that mMightHaveUnreportedJSException can only be
-    // true when we're expecting a JS exception.  We cannot send such messages
-    // over the IPC channel since there is no sane way of transferring the JS
-    // value over to the other side.  Callers should never do that.
-    MOZ_ASSERT_IF(aParam.IsJSException(), aParam.mMightHaveUnreportedJSException);
-    if (aParam.IsJSException()
-#ifdef DEBUG
-        || aParam.mMightHaveUnreportedJSException
-#endif
-        ) {
-      MOZ_CRASH("Cannot encode an ErrorResult representing a Javascript exception");
-    }
-
-    WriteParam(aMsg, aParam.mResult);
-    WriteParam(aMsg, aParam.IsErrorWithMessage());
-    if (aParam.IsErrorWithMessage()) {
-      aParam.SerializeMessage(aMsg);
-    }
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    paramType readValue;
-    if (!ReadParam(aMsg, aIter, &readValue.mResult)) {
-      return false;
-    }
-    bool hasMessage = false;
-    if (!ReadParam(aMsg, aIter, &hasMessage)) {
-      return false;
-    }
-    if (hasMessage && !readValue.DeserializeMessage(aMsg, aIter)) {
-      return false;
-    }
-    *aResult = Move(readValue);
-    return true;
-  }
-};
-
-}
-
-#endif
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -12,22 +12,16 @@
 #define mozilla_ErrorResult_h
 
 #include <stdarg.h>
 
 #include "js/Value.h"
 #include "nscore.h"
 #include "nsStringGlue.h"
 #include "mozilla/Assertions.h"
-#include "mozilla/Move.h"
-
-namespace IPC {
-class Message;
-template <typename> struct ParamTraits;
-}
 
 namespace mozilla {
 
 namespace dom {
 
 enum ErrNum {
 #define MSG_DEF(_name, _argc, _exn, _str) \
   _name,
@@ -57,22 +51,16 @@ public:
 
 #ifdef DEBUG
   ~ErrorResult() {
     MOZ_ASSERT_IF(IsErrorWithMessage(), !mMessage);
     MOZ_ASSERT(!mMightHaveUnreportedJSException);
   }
 #endif
 
-  ErrorResult(ErrorResult&& aRHS)
-  {
-    *this = Move(aRHS);
-  }
-  ErrorResult& operator=(ErrorResult&& aRHS);
-
   void Throw(nsresult rv) {
     MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
     MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
     MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
     MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
     MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
     MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
     MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
@@ -168,30 +156,25 @@ private:
   // ReportErrorWithMessage.
   // mJSException is set (and rooted) by ThrowJSException and unrooted
   // by ReportJSException.
   union {
     Message* mMessage; // valid when IsErrorWithMessage()
     JS::Value mJSException; // valid when IsJSException()
   };
 
-  friend struct IPC::ParamTraits<ErrorResult>;
-  void SerializeMessage(IPC::Message* aMsg) const;
-  bool DeserializeMessage(const IPC::Message* aMsg, void** aIter);
-
 #ifdef DEBUG
   // Used to keep track of codepaths that might throw JS exceptions,
   // for assertion purposes.
   bool mMightHaveUnreportedJSException;
 #endif
 
   // Not to be implemented, to make sure people always pass this by
   // reference, not by value.
   ErrorResult(const ErrorResult&) = delete;
-  void operator=(const ErrorResult&) = delete;
   void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
                              nsresult errorType);
 };
 
 /******************************************************************************
  ** Macros for checking results
  ******************************************************************************/
 
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -68,10 +68,9 @@ MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEE
 MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
 MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, JSEXN_TYPEERR, "Not allowed to define a non-configurable property on the WindowProxy object")
 MSG_DEF(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, 0, JSEXN_RANGEERR, "Invalid zoom and pan value.")
 MSG_DEF(MSG_INVALID_TRANSFORM_ANGLE_ERROR, 0, JSEXN_RANGEERR, "Invalid transform angle.")
 MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid response status code.")
 MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")
 MSG_DEF(MSG_INVALID_URL_SCHEME, 2, JSEXN_TYPEERR, "{0} URL {1} must be either http:// or https://.")
 MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
-MSG_DEF(MSG_RESPONSE_HAS_VARY_STAR, 0, JSEXN_TYPEERR, "Invalid Response object with a 'Vary: *' header.")
 MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -1,20 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 TEST_DIRS += ['test']
 
-EXPORTS.ipc += [
-    'ErrorIPCUtils.h',
-]
-
 EXPORTS.mozilla += [
     'ErrorResult.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'AtomList.h',
     'BindingDeclarations.h',
     'BindingUtils.h',
--- a/dom/cache/Cache.cpp
+++ b/dom/cache/Cache.cpp
@@ -447,26 +447,22 @@ Cache::RecvMatchAllResponse(RequestId aR
     promise->MaybeReject(aRv);
     return;
   }
 
   promise->MaybeResolve(responses);
 }
 
 void
-Cache::RecvAddAllResponse(RequestId aRequestId,
-                          const mozilla::ErrorResult& aError)
+Cache::RecvAddAllResponse(RequestId aRequestId, nsresult aRv)
 {
   nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
 
-  if (aError.Failed()) {
-    // TODO: Remove this const_cast (bug 1152078).
-    // It is safe for now since this ErrorResult is handed off to us by IPDL
-    // and is thrown into the trash afterwards.
-    promise->MaybeReject(const_cast<ErrorResult&>(aError));
+  if (NS_FAILED(aRv)) {
+    promise->MaybeReject(aRv);
     return;
   }
 
   promise->MaybeResolve(JS::UndefinedHandleValue);
 }
 
 void
 Cache::RecvPutResponse(RequestId aRequestId, nsresult aRv)
--- a/dom/cache/Cache.h
+++ b/dom/cache/Cache.h
@@ -76,18 +76,17 @@ public:
   // Called when CacheChild actor is being destroyed
   void DestroyInternal(CacheChild* aActor);
 
   // methods forwarded from CacheChild
   void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
                          const PCacheResponseOrVoid& aResponse);
   void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
                             const nsTArray<PCacheResponse>& aResponses);
-  void RecvAddAllResponse(RequestId aRequestId,
-                          const mozilla::ErrorResult& aError);
+  void RecvAddAllResponse(RequestId aRequestId, nsresult aRv);
   void RecvPutResponse(RequestId aRequestId, nsresult aRv);
 
   void RecvDeleteResponse(RequestId aRequestId, nsresult aRv,
                           bool aSuccess);
   void RecvKeysResponse(RequestId aRequestId, nsresult aRv,
                         const nsTArray<PCacheRequest>& aRequests);
 
   // TypeUtils methods
--- a/dom/cache/CacheChild.cpp
+++ b/dom/cache/CacheChild.cpp
@@ -141,23 +141,22 @@ CacheChild::RecvMatchAllResponse(const R
     return true;
   }
 
   listener->RecvMatchAllResponse(requestId, aRv, aResponses);
   return true;
 }
 
 bool
-CacheChild::RecvAddAllResponse(const RequestId& requestId,
-                               const mozilla::ErrorResult& aError)
+CacheChild::RecvAddAllResponse(const RequestId& requestId, const nsresult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheChild);
   nsRefPtr<Cache> listener = mListener;
   if (listener) {
-    listener->RecvAddAllResponse(requestId, aError);
+    listener->RecvAddAllResponse(requestId, aRv);
   }
   return true;
 }
 
 bool
 CacheChild::RecvPutResponse(const RequestId& aRequestId, const nsresult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheChild);
--- a/dom/cache/CacheChild.h
+++ b/dom/cache/CacheChild.h
@@ -50,17 +50,17 @@ private:
   virtual bool
   RecvMatchResponse(const RequestId& requestId, const nsresult& aRv,
                     const PCacheResponseOrVoid& aResponse) override;
   virtual bool
   RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv,
                        nsTArray<PCacheResponse>&& responses) override;
   virtual bool
   RecvAddAllResponse(const RequestId& requestId,
-                     const mozilla::ErrorResult& aError) override;
+                     const nsresult& aRv) override;
   virtual bool
   RecvPutResponse(const RequestId& aRequestId,
                   const nsresult& aRv) override;
   virtual bool
   RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv,
                      const bool& result) override;
   virtual bool
   RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
--- a/dom/cache/CacheParent.cpp
+++ b/dom/cache/CacheParent.cpp
@@ -18,17 +18,16 @@
 #include "mozilla/ipc/FileDescriptorSetParent.h"
 #include "mozilla/ipc/PFileDescriptorSetParent.h"
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
-using mozilla::dom::ErrNum;
 using mozilla::ipc::FileDescriptorSetParent;
 using mozilla::ipc::PFileDescriptorSetParent;
 
 // Declared in ActorUtils.h
 void
 DeallocPCacheParent(PCacheParent* aActor)
 {
   delete aActor;
@@ -117,20 +116,17 @@ CacheParent::RecvAddAll(const RequestId&
     requestStreams.AppendElement(DeserializeCacheStream(aRequests[i].body()));
   }
 
   nsRefPtr<FetchPut> fetchPut;
   nsresult rv = FetchPut::Create(this, mManager, aRequestId, mCacheId,
                                  aRequests, requestStreams,
                                  getter_AddRefs(fetchPut));
   if (NS_WARN_IF(NS_FAILED(rv))) {
-    MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR);
-    ErrorResult error;
-    error.Throw(rv);
-    if (!SendAddAllResponse(aRequestId, error)) {
+    if (!SendAddAllResponse(aRequestId, rv)) {
       // child process is gone, warn and allow actor to clean up normally
       NS_WARNING("Cache failed to send AddAll response.");
     }
     return true;
   }
 
   mFetchPutList.AppendElement(fetchPut.forget());
 
@@ -255,17 +251,17 @@ CacheParent::OnCacheKeys(RequestId aRequ
 
   if (!SendKeysResponse(aRequestId, aRv, requests.SendAsRequestList())) {
     // child process is gone, warn and allow actor to clean up normally
     NS_WARNING("Cache failed to send Keys response.");
   }
 }
 
 void
-CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv)
+CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv)
 {
   aFetchPut->ClearListener();
   mFetchPutList.RemoveElement(aFetchPut);
   if (!SendAddAllResponse(aRequestId, aRv)) {
     // child process is gone, warn and allow actor to clean up normally
     NS_WARNING("Cache failed to send AddAll response.");
   }
 }
--- a/dom/cache/CacheParent.h
+++ b/dom/cache/CacheParent.h
@@ -65,17 +65,17 @@ private:
   virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv,
                              bool aSuccess) override;
   virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv,
                            const nsTArray<SavedRequest>& aSavedRequests,
                            StreamList* aStreamList) override;
 
   // FetchPut::Listener methods
   virtual void OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId,
-                          const mozilla::ErrorResult& aRv) override;
+                          nsresult aRv) override;
 
   already_AddRefed<nsIInputStream>
   DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid);
 
   nsRefPtr<cache::Manager> mManager;
   const CacheId mCacheId;
   nsTArray<nsRefPtr<FetchPut>> mFetchPutList;
 };
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -939,19 +939,19 @@ DBSchema::MatchByVaryHeader(mozIStorageC
     // Extract the header names inside the Vary header value.
     nsAutoCString varyValue(varyValues[i]);
     char* rawBuffer = varyValue.BeginWriting();
     char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
     bool bailOut = false;
     for (; token;
          token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
       nsDependentCString header(token);
-      MOZ_ASSERT(!header.EqualsLiteral("*"),
-                 "We should have already caught this in "
-                 "TypeUtils::ToPCacheResponseWithoutBody()");
+      if (header.EqualsLiteral("*")) {
+        continue;
+      }
 
       ErrorResult errorResult;
       nsAutoCString queryValue;
       queryHeaders->Get(header, queryValue, errorResult);
       if (errorResult.Failed()) {
         errorResult.ClearMessage();
         MOZ_ASSERT(queryValue.IsEmpty());
       }
--- a/dom/cache/FetchPut.cpp
+++ b/dom/cache/FetchPut.cpp
@@ -131,16 +131,17 @@ FetchPut::FetchPut(Listener* aListener, 
                    const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams)
   : mListener(aListener)
   , mManager(aManager)
   , mRequestId(aRequestId)
   , mCacheId(aCacheId)
   , mInitiatingThread(NS_GetCurrentThread())
   , mStateList(aRequests.Length())
   , mPendingCount(0)
+  , mResult(NS_OK)
 {
   MOZ_ASSERT(mListener);
   MOZ_ASSERT(mManager);
   MOZ_ASSERT(aRequests.Length() == aRequestStreams.Length());
 
   for (uint32_t i = 0; i < aRequests.Length(); ++i) {
     State* s = mStateList.AppendElement();
     s->mPCacheRequest = aRequests[i];
@@ -151,17 +152,16 @@ FetchPut::FetchPut(Listener* aListener, 
 }
 
 FetchPut::~FetchPut()
 {
   MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
   MOZ_ASSERT(!mListener);
   mManager->RemoveListener(this);
   mManager->ReleaseCacheId(mCacheId);
-  mResult.ClearMessage(); // This may contain a TypeError.
 }
 
 nsresult
 FetchPut::DispatchToMainThread()
 {
   MOZ_ASSERT(!mRunnable);
 
   nsCOMPtr<nsIRunnable> runnable = new Runnable(this);
@@ -244,30 +244,30 @@ FetchPut::DoFetchOnMainThread()
 }
 
 void
 FetchPut::FetchComplete(FetchObserver* aObserver,
                         InternalResponse* aInternalResponse)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (aInternalResponse->IsError() && !mResult.Failed()) {
+  if (aInternalResponse->IsError() && NS_SUCCEEDED(mResult)) {
     MaybeSetError(NS_ERROR_FAILURE);
   }
 
   for (uint32_t i = 0; i < mStateList.Length(); ++i) {
     if (mStateList[i].mFetchObserver == aObserver) {
       ErrorResult rv;
       ToPCacheResponseWithoutBody(mStateList[i].mPCacheResponse,
                                   *aInternalResponse, rv);
       if (rv.Failed()) {
-        mResult = Move(rv);
-      } else {
-        aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream));
+        MaybeSetError(rv.ErrorCode());
+        return;
       }
+      aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream));
       mStateList[i].mFetchObserver = nullptr;
       MOZ_ASSERT(mPendingCount > 0);
       mPendingCount -= 1;
       MaybeCompleteOnMainThread();
       return;
     }
   }
 
@@ -286,17 +286,17 @@ FetchPut::MaybeCompleteOnMainThread()
   DispatchToInitiatingThread();
 }
 
 void
 FetchPut::DoPutOnWorkerThread()
 {
   MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
 
-  if (mResult.Failed()) {
+  if (NS_FAILED(mResult)) {
     MaybeNotifyListener();
     return;
   }
 
   // These allocate ~4.5k combined on the stack
   nsAutoTArray<CacheRequestResponse, 16> putList;
   nsAutoTArray<nsCOMPtr<nsIInputStream>, 16> requestStreamList;
   nsAutoTArray<nsCOMPtr<nsIInputStream>, 16> responseStreamList;
@@ -372,19 +372,19 @@ FetchPut::MatchInPutList(const PCacheReq
       // Extract the header names inside the Vary header value.
       nsAutoCString varyValue(varyHeaders[j]);
       char* rawBuffer = varyValue.BeginWriting();
       char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
       bool bailOut = false;
       for (; token;
            token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
         nsDependentCString header(token);
-        MOZ_ASSERT(!header.EqualsLiteral("*"),
-                   "We should have already caught this in "
-                   "TypeUtils::ToPCacheResponseWithoutBody()");
+        if (header.EqualsLiteral("*")) {
+          continue;
+        }
 
         ErrorResult headerRv;
         nsAutoCString value;
         requestHeaders->Get(header, value, headerRv);
         if (NS_WARN_IF(headerRv.Failed())) {
           headerRv.ClearMessage();
           MOZ_ASSERT(value.IsEmpty());
         }
@@ -423,31 +423,30 @@ FetchPut::OnCachePutAll(RequestId aReque
   MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
   MaybeSetError(aRv);
   MaybeNotifyListener();
 }
 
 void
 FetchPut::MaybeSetError(nsresult aRv)
 {
-  if (mResult.Failed() || NS_SUCCEEDED(aRv)) {
+  if (NS_FAILED(mResult) || NS_SUCCEEDED(aRv)) {
     return;
   }
-  mResult.Throw(aRv);
+  mResult = aRv;
 }
 
 void
 FetchPut::MaybeNotifyListener()
 {
   MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
   if (!mListener) {
     return;
   }
   mListener->OnFetchPut(this, mRequestId, mResult);
-  mResult.ClearMessage(); // This may contain a TypeError.
 }
 
 nsIGlobalObject*
 FetchPut::GetGlobalObject() const
 {
   MOZ_CRASH("No global object in parent-size FetchPut operation!");
 }
 
--- a/dom/cache/FetchPut.h
+++ b/dom/cache/FetchPut.h
@@ -4,17 +4,16 @@
  * 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/. */
 
 #ifndef mozilla_dom_cache_FetchPut_h
 #define mozilla_dom_cache_FetchPut_h
 
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
 #include "mozilla/dom/cache/Manager.h"
 #include "mozilla/dom/cache/PCacheTypes.h"
 #include "mozilla/dom/cache/Types.h"
 #include "mozilla/dom/cache/TypeUtils.h"
 #include "nsRefPtr.h"
 #include "nsTArray.h"
 #include <utility>
 
@@ -35,17 +34,17 @@ class FetchPut final : public Manager::L
 {
 public:
   typedef std::pair<nsRefPtr<Request>, nsRefPtr<Response>> PutPair;
 
   class Listener
   {
   public:
     virtual void
-    OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv) = 0;
+    OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv) = 0;
   };
 
   static nsresult
   Create(Listener* aListener, Manager* aManager,
          RequestId aRequestId, CacheId aCacheId,
          const nsTArray<PCacheRequest>& aRequests,
          const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams,
          FetchPut** aFetchPutOut);
@@ -100,17 +99,17 @@ private:
 
   Listener* mListener;
   nsRefPtr<Manager> mManager;
   const RequestId mRequestId;
   const CacheId mCacheId;
   nsCOMPtr<nsIThread> mInitiatingThread;
   nsTArray<State> mStateList;
   uint32_t mPendingCount;
-  ErrorResult mResult;
+  nsresult mResult;
   nsCOMPtr<nsIRunnable> mRunnable;
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::cache::FetchPut)
 };
 
 } // namespace cache
 } // namespace dom
--- a/dom/cache/PCache.ipdl
+++ b/dom/cache/PCache.ipdl
@@ -6,17 +6,16 @@ include protocol PBackground;
 include protocol PCachePushStream;
 include PCacheTypes;
 include protocol PFileDescriptorSet;
 
 include protocol PBlob; // FIXME: bug 792908
 include protocol PCacheStreamControl;
 
 using mozilla::dom::cache::RequestId from "mozilla/dom/cache/Types.h";
-using mozilla::ErrorResult from "ipc/ErrorIPCUtils.h";
 include "mozilla/dom/cache/IPCUtils.h";
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 protocol PCache
 {
@@ -31,17 +30,17 @@ parent:
   AddAll(RequestId requestId, PCacheRequest[] requests);
   Put(RequestId requestId, CacheRequestResponse aPut);
   Delete(RequestId requestId, PCacheRequest request, PCacheQueryParams params);
   Keys(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params);
 
 child:
   MatchResponse(RequestId requestId, nsresult aRv, PCacheResponseOrVoid aResponse);
   MatchAllResponse(RequestId requestId, nsresult aRv, PCacheResponse[] responses);
-  AddAllResponse(RequestId requestId, ErrorResult aRv);
+  AddAllResponse(RequestId requestId, nsresult aRv);
   PutResponse(RequestId requestId, nsresult aRv);
   DeleteResponse(RequestId requestId, nsresult aRv, bool success);
   KeysResponse(RequestId requestId, nsresult aRv, PCacheRequest[] requests);
 
 both:
   __delete__();
 };
 
--- a/dom/cache/TypeUtils.cpp
+++ b/dom/cache/TypeUtils.cpp
@@ -21,18 +21,16 @@
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "nsCOMPtr.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsIIPCSerializableInputStream.h"
 #include "nsStreamUtils.h"
 #include "nsString.h"
 #include "nsURLParsers.h"
-#include "nsCRT.h"
-#include "nsHttp.h"
 
 namespace {
 
 using mozilla::ErrorResult;
 using mozilla::unused;
 using mozilla::void_t;
 using mozilla::dom::cache::PCacheReadStream;
 using mozilla::ipc::BackgroundChild;
@@ -101,39 +99,16 @@ ProcessURL(nsAString& aUrl, bool* aSchem
   // ParsePath gives us query position relative to the start of the path
   queryPos += pathPos;
 
   // We want everything before the query sine we already removed the trailing
   // fragment
   *aUrlWithoutQueryOut = Substring(aUrl, 0, queryPos - 1);
 }
 
-static bool
-HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
-{
-  nsAutoTArray<nsCString, 16> varyHeaders;
-  ErrorResult rv;
-  aHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
-  MOZ_ALWAYS_TRUE(!rv.Failed());
-
-  for (uint32_t i = 0; i < varyHeaders.Length(); ++i) {
-    nsAutoCString varyValue(varyHeaders[i]);
-    char* rawBuffer = varyValue.BeginWriting();
-    char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
-    for (; token;
-         token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
-      nsDependentCString header(token);
-      if (header.EqualsLiteral("*")) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 void
 SerializeNormalStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut)
 {
   nsAutoTArray<FileDescriptor, 4> fds;
   SerializeInputStream(aStream, aReadStreamOut.params(), fds);
 
   PFileDescriptorSetChild* fdSet = nullptr;
   if (!fds.IsEmpty()) {
@@ -286,38 +261,31 @@ TypeUtils::ToPCacheResponseWithoutBody(P
       return;
     }
   }
 
   aOut.status() = aIn.GetStatus();
   aOut.statusText() = aIn.GetStatusText();
   nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
   MOZ_ASSERT(headers);
-  if (HasVaryStar(headers)) {
-    aRv.ThrowTypeError(MSG_RESPONSE_HAS_VARY_STAR);
-    return;
-  }
   headers->GetPHeaders(aOut.headers());
   aOut.headersGuard() = headers->Guard();
   aOut.securityInfo() = aIn.GetSecurityInfo();
 }
 
 void
 TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aRv)
 {
   if (aIn.BodyUsed()) {
     aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
     return;
   }
 
   nsRefPtr<InternalResponse> ir = aIn.GetInternalResponse();
   ToPCacheResponseWithoutBody(aOut, *ir, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
 
   nsCOMPtr<nsIInputStream> stream;
   aIn.GetBody(getter_AddRefs(stream));
   if (stream) {
     aIn.SetBodyUsed();
   }
 
   SerializeCacheStream(stream, &aOut.body(), aRv);
--- a/dom/cache/test/mochitest/test_cache_match_vary.js
+++ b/dom/cache/test/mochitest/test_cache_match_vary.js
@@ -102,69 +102,25 @@ function testBasicKeys() {
       return test.cache.keys(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}),
                              {ignoreVary: true});
     }).then(function(r) {
       return checkRequest(r);
     });
 }
 
 function testStar() {
-  function ensurePromiseRejected(promise) {
-    return promise
-      .then(function() {
-        ok(false, "Promise should be rejected");
-      }, function(err) {
-        is(err.name, "TypeError", "Attempting to store a Response with a Vary:* header must fail");
-      });
-  }
   var test;
-  return new Promise(function(resolve, reject) {
-    var cache;
-    caches.open(name).then(function(c) {
-      cache = c;
-      Promise.all([
-        ensurePromiseRejected(
-          cache.add(new Request(requestURL + "1", {headers: {"WhatToVary": "*"}}))),
-        ensurePromiseRejected(
-          cache.addAll([
-            new Request(requestURL + "2", {headers: {"WhatToVary": "*"}}),
-            requestURL + "3",
-          ])),
-        ensurePromiseRejected(
-          fetch(new Request(requestURL + "4", {headers: {"WhatToVary": "*"}}))
-            .then(function(response) {
-              return cache.put(requestURL + "4", response);
-            })),
-        ensurePromiseRejected(
-          cache.add(new Request(requestURL + "5", {headers: {"WhatToVary": "*,User-Agent"}}))),
-        ensurePromiseRejected(
-          cache.addAll([
-            new Request(requestURL + "6", {headers: {"WhatToVary": "*,User-Agent"}}),
-            requestURL + "7",
-          ])),
-        ensurePromiseRejected(
-          fetch(new Request(requestURL + "8", {headers: {"WhatToVary": "*,User-Agent"}}))
-            .then(function(response) {
-              return cache.put(requestURL + "8", response);
-            })),
-        ensurePromiseRejected(
-          cache.add(new Request(requestURL + "9", {headers: {"WhatToVary": "User-Agent,*"}}))),
-        ensurePromiseRejected(
-          cache.addAll([
-            new Request(requestURL + "10", {headers: {"WhatToVary": "User-Agent,*"}}),
-            requestURL + "10",
-          ])),
-        ensurePromiseRejected(
-          fetch(new Request(requestURL + "11", {headers: {"WhatToVary": "User-Agent,*"}}))
-            .then(function(response) {
-              return cache.put(requestURL + "11", response);
-            })),
-      ]).then(reject, resolve);
+  return setupTest({"WhatToVary": "*", "Cookie": "foo=bar"})
+    .then(function(t) {
+      test = t;
+      // Ensure that searching with a different Cookie header with Vary:* succeeds.
+      return test.cache.match(new Request(requestURL, {headers: {"Cookie": "bar=baz"}}));
+    }).then(function(r) {
+      return checkResponse(r, test.response, test.responseText);
     });
-  });
 }
 
 function testMatch() {
   var test;
   return setupTest({"WhatToVary": "Cookie", "Cookie": "foo=bar"})
     .then(function(t) {
       test = t;
       // Ensure that searching with a different Cookie header fails.
@@ -173,16 +129,33 @@ function testMatch() {
       is(typeof r, "undefined", "Searching for a request with a non-matching Cookie header should not succeed");
       // Ensure that searching with the same Cookie header succeeds.
       return test.cache.match(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}));
     }).then(function(r) {
       return checkResponse(r, test.response, test.responseText);
     });
 }
 
+function testStarAndAnotherHeader() {
+  var test;
+  return setupTest({"WhatToVary": "*,User-Agent"})
+    .then(function(t) {
+      test = t;
+      // Ensure that searching with a different User-Agent header fails.
+      return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}));
+    }).then(function(r) {
+      is(typeof r, "undefined", "Searching for a request with a non-matching User-Agent header should not succeed");
+      // Ensure that searching with a different User-Agent header but with ignoreVary succeeds.
+      return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}),
+                              {ignoreVary: true});
+    }).then(function(r) {
+      return checkResponse(r, test.response, test.responseText);
+    });
+}
+
 function testInvalidHeaderName() {
   var test;
   return setupTest({"WhatToVary": "Foo/Bar, User-Agent"})
     .then(function(t) {
       test = t;
       // Ensure that searching with a different User-Agent header fails.
       return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}));
     }).then(function(r) {
@@ -307,28 +280,28 @@ function testMultipleCacheEntries() {
     ]);
   });
 }
 
 // Make sure to clean up after each test step.
 function step(testPromise) {
   return testPromise.then(function() {
     caches.delete(name);
-  }, function() {
-    caches.delete(name);
   });
 }
 
 step(testBasics()).then(function() {
   return step(testBasicKeys());
 }).then(function() {
   return step(testStar());
 }).then(function() {
   return step(testMatch());
 }).then(function() {
+  return step(testStarAndAnotherHeader());
+}).then(function() {
   return step(testInvalidHeaderName());
 }).then(function() {
   return step(testMultipleHeaders());
 }).then(function() {
   return step(testMultipleCacheEntries());
 }).then(function() {
   testDone();
 });