Bug 1262671 - void** -> PickleIterator (r=froydnj)
authorBill McCloskey <billm@mozilla.com>
Wed, 20 Apr 2016 21:09:15 -0700
changeset 299331 63f6395614e8085c33d552e8c56e312df5c763a3
parent 299330 fff9ee7eaf1072bc237e6eaa48fb4705027cae5b
child 299332 4dc70010565c32f332c7f37eb34706571d690e18
push id77526
push userwmccloskey@mozilla.com
push dateFri, 27 May 2016 16:57:50 +0000
treeherdermozilla-inbound@b6fd41905d10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1262671
milestone49.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 1262671 - void** -> PickleIterator (r=froydnj)
chrome/RegistryMessageUtils.h
docshell/base/SerializedLoadContext.h
dom/asmjscache/AsmJSCache.cpp
dom/asmjscache/AsmJSCache.h
dom/bindings/BindingUtils.cpp
dom/bindings/ErrorIPCUtils.h
dom/bindings/ErrorResult.h
dom/bluetooth/ipc/BluetoothMessageUtils.h
dom/events/Event.cpp
dom/events/NotifyPaintEvent.cpp
dom/events/NotifyPaintEvent.h
dom/events/ScrollAreaEvent.cpp
dom/events/ScrollAreaEvent.h
dom/events/UIEvent.cpp
dom/events/UIEvent.h
dom/geolocation/nsGeoPositionIPCSerialiser.h
dom/indexedDB/SerializationHelpers.h
dom/interfaces/events/nsIDOMEvent.idl
dom/ipc/IdType.h
dom/ipc/PermissionMessageUtils.cpp
dom/ipc/PermissionMessageUtils.h
dom/ipc/StructuredCloneData.cpp
dom/ipc/StructuredCloneData.h
dom/ipc/TabMessageUtils.cpp
dom/ipc/TabMessageUtils.h
dom/media/gmp/GMPMessageUtils.h
dom/media/webrtc/WebrtcGlobal.h
dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
dom/plugins/ipc/NPEventAndroid.h
dom/plugins/ipc/NPEventOSX.h
dom/plugins/ipc/NPEventUnix.h
dom/plugins/ipc/NPEventWindows.h
dom/plugins/ipc/PluginMessageUtils.h
dom/telephony/ipc/TelephonyIPCSerializer.h
gfx/ipc/D3DMessageUtils.cpp
gfx/ipc/D3DMessageUtils.h
gfx/ipc/GfxMessageUtils.h
gfx/layers/apz/testutil/APZTestData.h
gfx/layers/composite/FrameUniformityData.h
gfx/layers/ipc/FenceUtils.cpp
gfx/layers/ipc/FenceUtils.h
gfx/layers/ipc/GonkNativeHandleUtils.cpp
gfx/layers/ipc/GonkNativeHandleUtils.h
gfx/layers/ipc/ShadowLayerUtils.h
gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
gfx/layers/ipc/ShadowLayerUtilsGralloc.h
gfx/layers/ipc/ShadowLayerUtilsX11.h
gfx/vr/ipc/VRMessageUtils.h
ipc/chromium/src/base/histogram.cc
ipc/chromium/src/base/histogram.h
ipc/chromium/src/base/pickle.cc
ipc/chromium/src/base/pickle.h
ipc/chromium/src/chrome/common/ipc_message.cc
ipc/chromium/src/chrome/common/ipc_message.h
ipc/chromium/src/chrome/common/ipc_message_utils.h
ipc/glue/BackgroundUtils.h
ipc/glue/IPCMessageUtils.h
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/SharedMemory.h
ipc/glue/Shmem.cpp
ipc/glue/Shmem.h
ipc/glue/Transport_posix.h
ipc/glue/Transport_win.h
ipc/ipdl/ipdl/lower.py
ipc/ipdl/test/cxx/IPDLUnitTestUtils.h
ipc/ipdl/test/cxx/TestActorPunning.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/VisibilityIPC.h
netwerk/ipc/NeckoMessageUtils.h
netwerk/protocol/http/PHttpChannelParams.h
netwerk/protocol/websocket/WebSocketFrame.cpp
netwerk/protocol/websocket/WebSocketFrame.h
toolkit/components/alerts/AlertNotificationIPCSerializer.h
widget/WidgetMessageUtils.h
widget/nsGUIEventIPC.h
--- a/chrome/RegistryMessageUtils.h
+++ b/chrome/RegistryMessageUtils.h
@@ -73,17 +73,17 @@ struct ParamTraits<SerializedURI>
   typedef SerializedURI paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.spec);
     WriteParam(aMsg, aParam.charset);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsCString spec, charset;
     if (ReadParam(aMsg, aIter, &spec) &&
         ReadParam(aMsg, aIter, &charset)) {
       aResult->spec = spec;
       aResult->charset = charset;
       return true;
     }
@@ -100,17 +100,17 @@ struct ParamTraits<ChromePackage>
   {
     WriteParam(aMsg, aParam.package);
     WriteParam(aMsg, aParam.contentBaseURI);
     WriteParam(aMsg, aParam.localeBaseURI);
     WriteParam(aMsg, aParam.skinBaseURI);
     WriteParam(aMsg, aParam.flags);
   }
   
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsCString package;
     SerializedURI contentBaseURI, localeBaseURI, skinBaseURI;
     uint32_t flags;
     
     if (ReadParam(aMsg, aIter, &package) &&
         ReadParam(aMsg, aIter, &contentBaseURI) &&
         ReadParam(aMsg, aIter, &localeBaseURI) &&
@@ -142,17 +142,17 @@ struct ParamTraits<SubstitutionMapping>
   
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.scheme);
     WriteParam(aMsg, aParam.path);
     WriteParam(aMsg, aParam.resolvedURI);
   }
   
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsCString scheme, path;
     SerializedURI resolvedURI;
     
     if (ReadParam(aMsg, aIter, &scheme) &&
         ReadParam(aMsg, aIter, &path) &&
         ReadParam(aMsg, aIter, &resolvedURI)) {
       aResult->scheme = scheme;
@@ -178,17 +178,17 @@ struct ParamTraits<OverrideMapping>
   typedef OverrideMapping paramType;
   
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.originalURI);
     WriteParam(aMsg, aParam.overrideURI);
   }
   
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     SerializedURI originalURI;
     SerializedURI overrideURI;
     
     if (ReadParam(aMsg, aIter, &originalURI) &&
         ReadParam(aMsg, aIter, &overrideURI)) {
       aResult->originalURI = originalURI;
       aResult->overrideURI = overrideURI;
--- a/docshell/base/SerializedLoadContext.h
+++ b/docshell/base/SerializedLoadContext.h
@@ -71,17 +71,17 @@ struct ParamTraits<SerializedLoadContext
     WriteParam(aMsg, aParam.mIsNotNull);
     WriteParam(aMsg, aParam.mIsContent);
     WriteParam(aMsg, aParam.mIsPrivateBitValid);
     WriteParam(aMsg, aParam.mUsePrivateBrowsing);
     WriteParam(aMsg, aParam.mUseRemoteTabs);
     WriteParam(aMsg, suffix);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsAutoCString suffix;
     if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) ||
         !ReadParam(aMsg, aIter, &aResult->mIsContent) ||
         !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) ||
         !ReadParam(aMsg, aIter, &aResult->mUsePrivateBrowsing) ||
         !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) ||
         !ReadParam(aMsg, aIter, &suffix)) {
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -1843,17 +1843,17 @@ ParamTraits<Metadata>::Write(Message* aM
     WriteParam(aMsg, entry.mFastHash);
     WriteParam(aMsg, entry.mNumChars);
     WriteParam(aMsg, entry.mFullHash);
     WriteParam(aMsg, entry.mModuleIndex);
   }
 }
 
 bool
-ParamTraits<Metadata>::Read(const Message* aMsg, void** aIter,
+ParamTraits<Metadata>::Read(const Message* aMsg, PickleIterator* aIter,
                             paramType* aResult)
 {
   for (unsigned i = 0; i < Metadata::kNumEntries; i++) {
     Metadata::Entry& entry = aResult->mEntries[i];
     if (!ReadParam(aMsg, aIter, &entry.mFastHash) ||
         !ReadParam(aMsg, aIter, &entry.mNumChars) ||
         !ReadParam(aMsg, aIter, &entry.mFullHash) ||
         !ReadParam(aMsg, aIter, &entry.mModuleIndex))
@@ -1882,17 +1882,17 @@ ParamTraits<WriteParams>::Write(Message*
   WriteParam(aMsg, aParam.mSize);
   WriteParam(aMsg, aParam.mFastHash);
   WriteParam(aMsg, aParam.mNumChars);
   WriteParam(aMsg, aParam.mFullHash);
   WriteParam(aMsg, aParam.mInstalled);
 }
 
 bool
-ParamTraits<WriteParams>::Read(const Message* aMsg, void** aIter,
+ParamTraits<WriteParams>::Read(const Message* aMsg, PickleIterator* aIter,
                                paramType* aResult)
 {
   return ReadParam(aMsg, aIter, &aResult->mSize) &&
          ReadParam(aMsg, aIter, &aResult->mFastHash) &&
          ReadParam(aMsg, aIter, &aResult->mNumChars) &&
          ReadParam(aMsg, aIter, &aResult->mFullHash) &&
          ReadParam(aMsg, aIter, &aResult->mInstalled);
 }
--- a/dom/asmjscache/AsmJSCache.h
+++ b/dom/asmjscache/AsmJSCache.h
@@ -164,26 +164,26 @@ struct ParamTraits<mozilla::dom::asmjsca
                                   mozilla::dom::asmjscache::NUM_OPEN_MODES>
 { };
 
 template <>
 struct ParamTraits<mozilla::dom::asmjscache::Metadata>
 {
   typedef mozilla::dom::asmjscache::Metadata paramType;
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
   static void Log(const paramType& aParam, std::wstring* aLog);
 };
 
 template <>
 struct ParamTraits<mozilla::dom::asmjscache::WriteParams>
 {
   typedef mozilla::dom::asmjscache::WriteParams paramType;
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
   static void Log(const paramType& aParam, std::wstring* aLog);
 };
 
 template <>
 struct ParamTraits<JS::AsmJSCacheResult> :
   public ContiguousEnumSerializer<JS::AsmJSCacheResult,
                                   JS::AsmJSCache_MIN,
                                   JS::AsmJSCache_LIMIT>
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -168,17 +168,17 @@ ErrorResult::SerializeMessage(IPC::Messa
   using namespace IPC;
   MOZ_ASSERT(mUnionState == HasMessage);
   MOZ_ASSERT(mMessage);
   WriteParam(aMsg, mMessage->mArgs);
   WriteParam(aMsg, mMessage->mErrorNumber);
 }
 
 bool
-ErrorResult::DeserializeMessage(const IPC::Message* aMsg, void** aIter)
+ErrorResult::DeserializeMessage(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   using namespace IPC;
   nsAutoPtr<Message> readMessage(new Message());
   if (!ReadParam(aMsg, aIter, &readMessage->mArgs) ||
       !ReadParam(aMsg, aIter, &readMessage->mErrorNumber)) {
     return false;
   }
   if (!readMessage->HasCorrectNumberOfArguments()) {
@@ -290,17 +290,17 @@ ErrorResult::SerializeDOMExceptionInfo(I
   using namespace IPC;
   MOZ_ASSERT(mDOMExceptionInfo);
   MOZ_ASSERT(mUnionState == HasDOMExceptionInfo);
   WriteParam(aMsg, mDOMExceptionInfo->mMessage);
   WriteParam(aMsg, mDOMExceptionInfo->mRv);
 }
 
 bool
-ErrorResult::DeserializeDOMExceptionInfo(const IPC::Message* aMsg, void** aIter)
+ErrorResult::DeserializeDOMExceptionInfo(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   using namespace IPC;
   nsCString message;
   nsresult rv;
   if (!ReadParam(aMsg, aIter, &message) ||
       !ReadParam(aMsg, aIter, &rv)) {
     return false;
   }
--- a/dom/bindings/ErrorIPCUtils.h
+++ b/dom/bindings/ErrorIPCUtils.h
@@ -45,17 +45,17 @@ struct ParamTraits<mozilla::ErrorResult>
     WriteParam(aMsg, aParam.IsDOMException());
     if (aParam.IsErrorWithMessage()) {
       aParam.SerializeMessage(aMsg);
     } else if (aParam.IsDOMException()) {
       aParam.SerializeDOMExceptionInfo(aMsg);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     paramType readValue;
     if (!ReadParam(aMsg, aIter, &readValue.mResult)) {
       return false;
     }
     bool hasMessage = false;
     if (!ReadParam(aMsg, aIter, &hasMessage)) {
       return false;
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -31,16 +31,17 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/Move.h"
 #include "nsTArray.h"
 
 namespace IPC {
 class Message;
 template <typename> struct ParamTraits;
 } // namespace IPC
+class PickleIterator;
 
 namespace mozilla {
 
 namespace dom {
 
 enum ErrNum {
 #define MSG_DEF(_name, _argc, _exn, _str) \
   _name,
@@ -302,20 +303,20 @@ private:
     HasDOMExceptionInfo,
     HasJSException,
     HasNothing
   };
 #endif // DEBUG
 
   friend struct IPC::ParamTraits<ErrorResult>;
   void SerializeMessage(IPC::Message* aMsg) const;
-  bool DeserializeMessage(const IPC::Message* aMsg, void** aIter);
+  bool DeserializeMessage(const IPC::Message* aMsg, PickleIterator* aIter);
 
   void SerializeDOMExceptionInfo(IPC::Message* aMsg) const;
-  bool DeserializeDOMExceptionInfo(const IPC::Message* aMsg, void** aIter);
+  bool DeserializeDOMExceptionInfo(const IPC::Message* aMsg, PickleIterator* aIter);
 
   // Helper method that creates a new Message for this ErrorResult,
   // and returns the arguments array from that Message.
   nsTArray<nsString>& CreateErrorMessageHelper(const dom::ErrNum errorNumber, nsresult errorType);
 
   template<dom::ErrNum errorNumber, typename... Ts>
   void ThrowErrorWithMessage(nsresult errorType, Ts&&... messageArgs)
   {
--- a/dom/bluetooth/ipc/BluetoothMessageUtils.h
+++ b/dom/bluetooth/ipc/BluetoothMessageUtils.h
@@ -19,17 +19,17 @@ struct ParamTraits<mozilla::dom::bluetoo
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aParam.mAddr); ++i) {
       WriteParam(aMsg, aParam.mAddr[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aResult->mAddr); ++i) {
       if (!ReadParam(aMsg, aIter, aResult->mAddr + i)) {
         return false;
       }
     }
     return true;
   }
@@ -56,17 +56,17 @@ struct ParamTraits<mozilla::dom::bluetoo
     }
 
     WriteParam(aMsg, length);
     for (uint8_t i = 0; i < length; ++i) {
       WriteParam(aMsg, aParam.mPinCode[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->mLength)) {
       return false;
     }
 
     auto maxLength = MOZ_ARRAY_LENGTH(aResult->mPinCode);
 
     if (aResult->mLength > maxLength) {
@@ -92,17 +92,17 @@ struct ParamTraits<mozilla::dom::bluetoo
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mLength);
     for (size_t i = 0; i < aParam.mLength; ++i) {
       WriteParam(aMsg, aParam.mName[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->mLength)) {
       return false;
     }
     if (aResult->mLength > MOZ_ARRAY_LENGTH(aResult->mName)) {
       return false;
     }
     for (uint8_t i = 0; i < aResult->mLength; ++i) {
@@ -153,17 +153,17 @@ struct ParamTraits<mozilla::dom::bluetoo
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     for (uint8_t i = 0; i < 16; i++) {
       WriteParam(aMsg, aParam.mUuid[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     for (uint8_t i = 0; i < 16; i++) {
       if (!ReadParam(aMsg, aIter, &(aResult->mUuid[i]))) {
         return false;
       }
     }
 
     return true;
@@ -176,17 +176,17 @@ struct ParamTraits<mozilla::dom::bluetoo
   typedef mozilla::dom::bluetooth::BluetoothGattId paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mUuid);
     WriteParam(aMsg, aParam.mInstanceId);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mUuid)) ||
         !ReadParam(aMsg, aIter, &(aResult->mInstanceId))) {
       return false;
     }
 
     return true;
   }
@@ -198,17 +198,17 @@ struct ParamTraits<mozilla::dom::bluetoo
   typedef mozilla::dom::bluetooth::BluetoothGattServiceId paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mId);
     WriteParam(aMsg, aParam.mIsPrimary);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIsPrimary))) {
       return false;
     }
 
     return true;
   }
@@ -221,17 +221,17 @@ struct ParamTraits<mozilla::dom::bluetoo
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mId);
     WriteParam(aMsg, aParam.mProperties);
     WriteParam(aMsg, aParam.mWriteType);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mProperties)) ||
         !ReadParam(aMsg, aIter, &(aResult->mWriteType))) {
       return false;
     }
 
     return true;
@@ -243,17 +243,17 @@ struct ParamTraits<mozilla::dom::bluetoo
 {
   typedef mozilla::dom::bluetooth::BluetoothAttributeHandle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mHandle);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mHandle))) {
       return false;
     }
 
     return true;
   }
 };
@@ -274,17 +274,17 @@ struct ParamTraits<mozilla::dom::bluetoo
     WriteParam(aMsg, aParam.mOffset);
     WriteParam(aMsg, length);
     WriteParam(aMsg, aParam.mAuthReq);
     for (uint16_t i = 0; i < length; i++) {
       WriteParam(aMsg, aParam.mValue[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mHandle)) ||
         !ReadParam(aMsg, aIter, &(aResult->mOffset)) ||
         !ReadParam(aMsg, aIter, &(aResult->mLength)) ||
         !ReadParam(aMsg, aIter, &(aResult->mAuthReq))) {
       return false;
     }
 
@@ -307,17 +307,17 @@ struct ParamTraits<mozilla::dom::bluetoo
 {
   typedef mozilla::dom::bluetooth::ControlPlayStatus paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<uint8_t>(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint8_t value;
     if (!ReadParam(aMsg, aIter, &value)) {
       return false;
     }
 
     mozilla::dom::bluetooth::ControlPlayStatus result =
       static_cast<mozilla::dom::bluetooth::ControlPlayStatus>(value);
@@ -347,17 +347,17 @@ struct ParamTraits<mozilla::dom::bluetoo
     WriteParam(aMsg, aParam.mAppearance);
     WriteParam(aMsg, aParam.mIncludeDevName);
     WriteParam(aMsg, aParam.mIncludeTxPower);
     WriteParam(aMsg, aParam.mManufacturerData);
     WriteParam(aMsg, aParam.mServiceData);
     WriteParam(aMsg, aParam.mServiceUuids);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mAppearance)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIncludeDevName)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIncludeTxPower)) ||
         !ReadParam(aMsg, aIter, &(aResult->mManufacturerData)) ||
         !ReadParam(aMsg, aIter, &(aResult->mServiceData)) ||
         !ReadParam(aMsg, aIter, &(aResult->mServiceUuids))) {
       return false;
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -1164,17 +1164,17 @@ Event::Serialize(IPC::Message* aMsg, boo
   IPC::WriteParam(aMsg, Bubbles());
   IPC::WriteParam(aMsg, Cancelable());
   IPC::WriteParam(aMsg, IsTrusted());
 
   // No timestamp serialization for now!
 }
 
 NS_IMETHODIMP_(bool)
-Event::Deserialize(const IPC::Message* aMsg, void** aIter)
+Event::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   nsString type;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &type), false);
 
   bool bubbles = false;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), false);
 
   bool cancelable = false;
--- a/dom/events/NotifyPaintEvent.cpp
+++ b/dom/events/NotifyPaintEvent.cpp
@@ -135,17 +135,17 @@ NotifyPaintEvent::Serialize(IPC::Message
   IPC::WriteParam(aMsg, length);
   for (uint32_t i = 0; i < length; ++i) {
     IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect);
     IPC::WriteParam(aMsg, mInvalidateRequests[i].mFlags);
   }
 }
 
 NS_IMETHODIMP_(bool)
-NotifyPaintEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+NotifyPaintEvent::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   NS_ENSURE_TRUE(Event::Deserialize(aMsg, aIter), false);
 
   uint32_t length = 0;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &length), false);
   mInvalidateRequests.SetCapacity(length);
   for (uint32_t i = 0; i < length; ++i) {
     nsInvalidateRequestList::Request req;
--- a/dom/events/NotifyPaintEvent.h
+++ b/dom/events/NotifyPaintEvent.h
@@ -38,17 +38,17 @@ public:
 
   // Forward to base class
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() override
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) override;
-  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) override;
+  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) override;
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return NotifyPaintEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   already_AddRefed<DOMRectList> ClientRects();
 
--- a/dom/events/ScrollAreaEvent.cpp
+++ b/dom/events/ScrollAreaEvent.cpp
@@ -55,17 +55,17 @@ ScrollAreaEvent::Serialize(IPC::Message*
 
   IPC::WriteParam(aMsg, X());
   IPC::WriteParam(aMsg, Y());
   IPC::WriteParam(aMsg, Width());
   IPC::WriteParam(aMsg, Height());
 }
 
 NS_IMETHODIMP_(bool)
-ScrollAreaEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+ScrollAreaEvent::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   NS_ENSURE_TRUE(Event::Deserialize(aMsg, aIter), false);
 
   float x, y, width, height;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &x), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &y), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &width), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &height), false);
--- a/dom/events/ScrollAreaEvent.h
+++ b/dom/events/ScrollAreaEvent.h
@@ -28,17 +28,17 @@ public:
   NS_FORWARD_NSIDOMUIEVENT(UIEvent::)
 
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() override
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) override;
-  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) override;
+  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) override;
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return ScrollAreaEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   float X() const
   {
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -393,17 +393,17 @@ UIEvent::Serialize(IPC::Message* aMsg, b
   Event::Serialize(aMsg, false);
 
   int32_t detail = 0;
   GetDetail(&detail);
   IPC::WriteParam(aMsg, detail);
 }
 
 NS_IMETHODIMP_(bool)
-UIEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+UIEvent::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   NS_ENSURE_TRUE(Event::Deserialize(aMsg, aIter), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &mDetail), false);
   return true;
 }
 
 // XXX Following struct and array are used only in
 //     UIEvent::ComputeModifierState(), but if we define them in it,
--- a/dom/events/UIEvent.h
+++ b/dom/events/UIEvent.h
@@ -33,17 +33,17 @@ public:
 
   // nsIDOMUIEvent Interface
   NS_DECL_NSIDOMUIEVENT
 
   // Forward to Event
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() override;
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) override;
-  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) override;
+  NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) override;
 
 
   static already_AddRefed<UIEvent> Constructor(const GlobalObject& aGlobal,
                                                const nsAString& aType,
                                                const UIEventInit& aParam,
                                                ErrorResult& aRv);
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
@@ -134,17 +134,17 @@ protected:
   }                                                         \
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg,           \
                               bool aSerializeInterfaceType) \
     override                                                \
   {                                                         \
     UIEvent::Serialize(aMsg, aSerializeInterfaceType);      \
   }                                                         \
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg,   \
-                                void** aIter) override      \
+                                PickleIterator* aIter) override \
   {                                                         \
     return UIEvent::Deserialize(aMsg, aIter);               \
   }
 
 already_AddRefed<mozilla::dom::UIEvent>
 NS_NewDOMUIEvent(mozilla::dom::EventTarget* aOwner,
                  nsPresContext* aPresContext,
                  mozilla::WidgetGUIEvent* aEvent);
--- a/dom/geolocation/nsGeoPositionIPCSerialiser.h
+++ b/dom/geolocation/nsGeoPositionIPCSerialiser.h
@@ -48,17 +48,17 @@ struct ParamTraits<nsIDOMGeoPositionCoor
     aParam->GetHeading(&coordData);
     WriteParam(aMsg, coordData);
 
     aParam->GetSpeed(&coordData);
     WriteParam(aMsg, coordData);
   }
 
   // Function to de-serialize a geoposition
-  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
       *aResult = 0;
       return true;
@@ -114,17 +114,17 @@ struct ParamTraits<nsIDOMGeoPosition*>
     WriteParam(aMsg, timeStamp);
 
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     aParam->GetCoords(getter_AddRefs(coords));
     WriteParam(aMsg, coords.get());
   }
 
   // Function to de-serialize a geoposition
-  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
       *aResult = 0;
       return true;
--- a/dom/indexedDB/SerializationHelpers.h
+++ b/dom/indexedDB/SerializationHelpers.h
@@ -21,17 +21,17 @@ struct ParamTraits<mozilla::dom::indexed
 {
   typedef mozilla::dom::indexedDB::Key paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mBuffer);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mBuffer);
   }
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
     LogParam(aParam.mBuffer, aLog);
   }
@@ -50,17 +50,17 @@ struct ParamTraits<mozilla::dom::indexed
   typedef mozilla::dom::indexedDB::KeyPath paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mType);
     WriteParam(aMsg, aParam.mStrings);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mType) &&
            ReadParam(aMsg, aIter, &aResult->mStrings);
   }
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
     LogParam(aParam.mStrings, aLog);
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -6,28 +6,30 @@
 #include "domstubs.idl"
 
 interface nsIDOMEventTarget;
 
 [ptr] native WidgetEvent(mozilla::WidgetEvent);
 [ptr] native DOMEventPtr(mozilla::dom::Event);
 [ptr] native IPCMessagePtr(IPC::Message);
 [ptr] native ConstIPCMessagePtr(const IPC::Message);
+[ptr] native PickleIterator(PickleIterator);
 [ptr] native EventTargetPtr(mozilla::dom::EventTarget);
 %{C++
 #ifdef ERROR
 #undef ERROR
 #endif
 
 #include "mozilla/EventForwards.h"
 class nsPresContext;
 class nsInvalidateRequestList;
 namespace IPC {
 class Message;
 }
+class PickleIterator;
 namespace mozilla {
 namespace dom {
 class Event;
 class EventTarget;
 } // namespace dom
 } // namespace mozilla
 %}
 
@@ -206,13 +208,13 @@ interface nsIDOMEvent : nsISupports
 
   [noscript] void duplicatePrivateData();
   [noscript] void setTarget(in nsIDOMEventTarget aTarget);
   [notxpcom] boolean IsDispatchStopped();
   [notxpcom] WidgetEvent WidgetEventPtr();
   [noscript,notxpcom] void SetTrusted(in boolean aTrusted);
   [notxpcom] void Serialize(in IPCMessagePtr aMsg,
                             in boolean aSerializeInterfaceType);
-  [notxpcom] boolean Deserialize(in ConstIPCMessagePtr aMsg, out voidPtr aIter);
+  [notxpcom] boolean Deserialize(in ConstIPCMessagePtr aMsg, in PickleIterator aIter);
   [noscript,notxpcom] void SetOwner(in EventTargetPtr aOwner);
   [notxpcom] DOMEventPtr InternalDOMEvent();
   [noscript] void stopCrossProcessForwarding();
 };
--- a/dom/ipc/IdType.h
+++ b/dom/ipc/IdType.h
@@ -57,17 +57,17 @@ struct ParamTraits<mozilla::dom::IdType<
 {
   typedef mozilla::dom::IdType<T> paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mId);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mId);
   }
 };
 
 } // namespace IPC
 
 #endif // mozilla_dom_IdType_h
--- a/dom/ipc/PermissionMessageUtils.cpp
+++ b/dom/ipc/PermissionMessageUtils.cpp
@@ -32,17 +32,17 @@ ParamTraits<Principal>::Write(Message* a
     NS_RUNTIMEABORT("Unable to serialize principal.");
     return;
   }
 
   WriteParam(aMsg, principalString);
 }
 
 bool
-ParamTraits<Principal>::Read(const Message* aMsg, void** aIter, paramType* aResult)
+ParamTraits<Principal>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
 {
   bool isNull;
   if (!ReadParam(aMsg, aIter, &isNull)) {
     return false;
   }
 
   if (isNull) {
     aResult->mPrincipal = nullptr;
--- a/dom/ipc/PermissionMessageUtils.h
+++ b/dom/ipc/PermissionMessageUtils.h
@@ -34,15 +34,15 @@ private:
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 template <>
 struct ParamTraits<Principal>
 {
   typedef Principal paramType;
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 } // namespace IPC
 
 #endif // mozilla_dom_permission_message_utils_h__
 
--- a/dom/ipc/StructuredCloneData.cpp
+++ b/dom/ipc/StructuredCloneData.cpp
@@ -100,17 +100,17 @@ StructuredCloneData::WriteIPCParams(IPC:
   if (DataLength()) {
     // Structured clone data must be 64-bit aligned.
     aMsg->WriteBytes(Data(), DataLength(), sizeof(uint64_t));
   }
 }
 
 bool
 StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg,
-                                   void** aIter)
+                                   PickleIterator* aIter)
 {
   MOZ_ASSERT(!Data());
 
   size_t dataLength = 0;
   if (!ReadParam(aMsg, aIter, &dataLength)) {
     return false;
   }
 
--- a/dom/ipc/StructuredCloneData.h
+++ b/dom/ipc/StructuredCloneData.h
@@ -10,16 +10,17 @@
 #include <algorithm>
 #include "mozilla/RefPtr.h"
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "nsISupportsImpl.h"
 
 namespace IPC {
 class Message;
 }
+class PickleIterator;
 
 namespace mozilla {
 namespace dom {
 namespace ipc {
 
 class SharedJSAllocatedData final
 {
 public:
@@ -132,17 +133,17 @@ public:
 
   SharedJSAllocatedData* SharedData() const
   {
     return mSharedData;
   }
 
   // For IPC serialization
   void WriteIPCParams(IPC::Message* aMessage) const;
-  bool ReadIPCParams(const IPC::Message* aMessage, void** aIter);
+  bool ReadIPCParams(const IPC::Message* aMessage, PickleIterator* aIter);
 
 private:
   uint64_t* MOZ_NON_OWNING_REF mExternalData;
   size_t mExternalDataLength;
 
   RefPtr<SharedJSAllocatedData> mSharedData;
 };
 
--- a/dom/ipc/TabMessageUtils.cpp
+++ b/dom/ipc/TabMessageUtils.cpp
@@ -8,17 +8,17 @@
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/TabMessageUtils.h"
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 bool
-ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
+ReadRemoteEvent(const IPC::Message* aMsg, PickleIterator* aIter,
                 RemoteDOMEvent* aResult)
 {
   aResult->mEvent = nullptr;
   nsString type;
   NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &type), false);
 
   aResult->mEvent = EventDispatcher::CreateEvent(nullptr, nullptr, nullptr,
                                                  type);
--- a/dom/ipc/TabMessageUtils.h
+++ b/dom/ipc/TabMessageUtils.h
@@ -19,17 +19,17 @@
 namespace mozilla {
 namespace dom {
 struct RemoteDOMEvent
 {
   // Make sure to set the owner after deserializing.
   nsCOMPtr<nsIDOMEvent> mEvent;
 };
 
-bool ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
+bool ReadRemoteEvent(const IPC::Message* aMsg, PickleIterator* aIter,
                      mozilla::dom::RemoteDOMEvent* aResult);
 
 #ifdef MOZ_CRASHREPORTER
 typedef CrashReporter::ThreadId NativeThreadId;
 #else
 // unused in this case
 typedef int32_t NativeThreadId;
 #endif
@@ -44,17 +44,17 @@ struct ParamTraits<mozilla::dom::RemoteD
 {
   typedef mozilla::dom::RemoteDOMEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aParam.mEvent->Serialize(aMsg, true);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return mozilla::dom::ReadRemoteEvent(aMsg, aIter, aResult);
   }
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
   }
 };
@@ -70,17 +70,17 @@ struct ParamTraits<mozilla::dom::AudioCh
   }
 
   static void Write(Message* aMsg, const paramType& aValue)
   {
     MOZ_ASSERT(IsLegalValue(aValue));
     WriteParam(aMsg, (uint32_t)aValue);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint32_t value;
     if(!ReadParam(aMsg, aIter, &value) ||
        !IsLegalValue(paramType(value))) {
       return false;
     }
     *aResult = paramType(value);
     return true;
--- a/dom/media/gmp/GMPMessageUtils.h
+++ b/dom/media/gmp/GMPMessageUtils.h
@@ -127,17 +127,17 @@ struct ParamTraits<GMPSimulcastStream>
     WriteParam(aMsg, aParam.mHeight);
     WriteParam(aMsg, aParam.mNumberOfTemporalLayers);
     WriteParam(aMsg, aParam.mMaxBitrate);
     WriteParam(aMsg, aParam.mTargetBitrate);
     WriteParam(aMsg, aParam.mMinBitrate);
     WriteParam(aMsg, aParam.mQPMax);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (ReadParam(aMsg, aIter, &(aResult->mWidth)) &&
         ReadParam(aMsg, aIter, &(aResult->mHeight)) &&
         ReadParam(aMsg, aIter, &(aResult->mNumberOfTemporalLayers)) &&
         ReadParam(aMsg, aIter, &(aResult->mMaxBitrate)) &&
         ReadParam(aMsg, aIter, &(aResult->mTargetBitrate)) &&
         ReadParam(aMsg, aIter, &(aResult->mMinBitrate)) &&
         ReadParam(aMsg, aIter, &(aResult->mQPMax))) {
@@ -176,17 +176,17 @@ struct ParamTraits<GMPVideoCodec>
     WriteParam(aMsg, aParam.mQPMax);
     WriteParam(aMsg, aParam.mNumberOfSimulcastStreams);
     for (uint32_t i = 0; i < aParam.mNumberOfSimulcastStreams; i++) {
       WriteParam(aMsg, aParam.mSimulcastStream[i]);
     }
     WriteParam(aMsg, aParam.mMode);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // NOTE: make sure this matches any versions supported
     if (!ReadParam(aMsg, aIter, &(aResult->mGMPApiVersion)) ||
       aResult->mGMPApiVersion != kGMPVersion33) {
         return false;
     }
     if (!ReadParam(aMsg, aIter, &(aResult->mCodecType))) {
       return false;
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -26,17 +26,17 @@ struct ParamTraits<mozilla::dom::Optiona
       WriteParam(aMsg, true);
       WriteParam(aMsg, aParam.Value());
       return;
     }
 
     WriteParam(aMsg, false);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool was_passed = false;
 
     if (!ReadParam(aMsg, aIter, &was_passed)) {
       return false;
     }
 
     aResult->Reset(); //XXX Optional_base seems to reach this point with isSome true.
@@ -56,17 +56,17 @@ struct ParamTraits<mozilla::dom::Sequenc
 {
   typedef mozilla::dom::Sequence<T> paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<const FallibleTArray<T>&>(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, dynamic_cast<FallibleTArray<T>*>(aResult));
   }
 };
 
 template<>
 struct ParamTraits<mozilla::dom::RTCStatsType> :
   public ContiguousEnumSerializer<
@@ -109,17 +109,17 @@ struct ParamTraits<mozilla::dom::RTCStat
     WriteParam(aMsg, aParam.mMediaStreamTrackStats);
     WriteParam(aMsg, aParam.mOutboundRTPStreamStats);
     WriteParam(aMsg, aParam.mPcid);
     WriteParam(aMsg, aParam.mRemoteSdp);
     WriteParam(aMsg, aParam.mTimestamp);
     WriteParam(aMsg, aParam.mTransportStats);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mClosed)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCodecStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIceCandidatePairStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIceCandidateStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIceComponentStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mInboundRTPStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mLocalSdp)) ||
@@ -142,17 +142,17 @@ typedef mozilla::dom::RTCStats RTCStats;
 static void WriteRTCStats(Message* aMsg, const RTCStats& aParam)
 {
   // RTCStats base class
   WriteParam(aMsg, aParam.mId);
   WriteParam(aMsg, aParam.mTimestamp);
   WriteParam(aMsg, aParam.mType);
 }
 
-static bool ReadRTCStats(const Message* aMsg, void** aIter, RTCStats* aResult)
+static bool ReadRTCStats(const Message* aMsg, PickleIterator* aIter, RTCStats* aResult)
 {
   // RTCStats base class
   if (!ReadParam(aMsg, aIter, &(aResult->mId)) ||
       !ReadParam(aMsg, aIter, &(aResult->mTimestamp)) ||
       !ReadParam(aMsg, aIter, &(aResult->mType))) {
     return false;
   }
 
@@ -169,17 +169,17 @@ struct ParamTraits<mozilla::dom::RTCCode
     WriteParam(aMsg, aParam.mChannels);
     WriteParam(aMsg, aParam.mClockRate);
     WriteParam(aMsg, aParam.mCodec);
     WriteParam(aMsg, aParam.mParameters);
     WriteParam(aMsg, aParam.mPayloadType);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mChannels)) ||
         !ReadParam(aMsg, aIter, &(aResult->mClockRate)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCodec)) ||
         !ReadParam(aMsg, aIter, &(aResult->mParameters)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPayloadType)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
@@ -202,17 +202,17 @@ struct ParamTraits<mozilla::dom::RTCIceC
     WriteParam(aMsg, aParam.mNominated);
     WriteParam(aMsg, aParam.mReadable);
     WriteParam(aMsg, aParam.mRemoteCandidateId);
     WriteParam(aMsg, aParam.mSelected);
     WriteParam(aMsg, aParam.mState);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mLocalCandidateId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPriority)) ||
         !ReadParam(aMsg, aIter, &(aResult->mNominated)) ||
         !ReadParam(aMsg, aIter, &(aResult->mReadable)) ||
         !ReadParam(aMsg, aIter, &(aResult->mRemoteCandidateId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mSelected)) ||
@@ -237,17 +237,17 @@ struct ParamTraits<mozilla::dom::RTCIceC
     WriteParam(aMsg, aParam.mComponentId);
     WriteParam(aMsg, aParam.mIpAddress);
     WriteParam(aMsg, aParam.mMozLocalTransport);
     WriteParam(aMsg, aParam.mPortNumber);
     WriteParam(aMsg, aParam.mTransport);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mCandidateId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIpAddress)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
@@ -269,17 +269,17 @@ struct ParamTraits<mozilla::dom::RTCIceC
     WriteParam(aMsg, aParam.mActiveConnection);
     WriteParam(aMsg, aParam.mBytesReceived);
     WriteParam(aMsg, aParam.mBytesSent);
     WriteParam(aMsg, aParam.mComponent);
     WriteParam(aMsg, aParam.mTransportId);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mActiveConnection)) ||
         !ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
         !ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
         !ReadParam(aMsg, aIter, &(aResult->mComponent)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransportId)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
@@ -302,17 +302,17 @@ static void WriteRTCRTPStreamStats(
     WriteParam(aMsg, aParam.mMediaTrackId);
     WriteParam(aMsg, aParam.mMediaType);
     WriteParam(aMsg, aParam.mRemoteId);
     WriteParam(aMsg, aParam.mSsrc);
     WriteParam(aMsg, aParam.mTransportId);
 }
 
 static bool ReadRTCRTPStreamStats(
-              const Message* aMsg, void** aIter,
+              const Message* aMsg, PickleIterator* aIter,
               mozilla::dom::RTCRTPStreamStats* aResult)
 {
   if (!ReadParam(aMsg, aIter, &(aResult->mBitrateMean)) ||
       !ReadParam(aMsg, aIter, &(aResult->mBitrateStdDev)) ||
       !ReadParam(aMsg, aIter, &(aResult->mCodecId)) ||
       !ReadParam(aMsg, aIter, &(aResult->mFramerateMean)) ||
       !ReadParam(aMsg, aIter, &(aResult->mFramerateStdDev)) ||
       !ReadParam(aMsg, aIter, &(aResult->mIsRemote)) ||
@@ -341,17 +341,17 @@ struct ParamTraits<mozilla::dom::RTCInbo
     WriteParam(aMsg, aParam.mMozJitterBufferDelay);
     WriteParam(aMsg, aParam.mMozRtt);
     WriteParam(aMsg, aParam.mPacketsLost);
     WriteParam(aMsg, aParam.mPacketsReceived);
     WriteRTCRTPStreamStats(aMsg, aParam);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDiscardedPackets)) ||
         !ReadParam(aMsg, aIter, &(aResult->mJitter)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozAvSyncDelay)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozJitterBufferDelay)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozRtt)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPacketsLost)) ||
@@ -375,17 +375,17 @@ struct ParamTraits<mozilla::dom::RTCOutb
     WriteParam(aMsg, aParam.mBytesSent);
     WriteParam(aMsg, aParam.mDroppedFrames);
     WriteParam(aMsg, aParam.mPacketsSent);
     WriteParam(aMsg, aParam.mTargetBitrate);
     WriteRTCRTPStreamStats(aMsg, aParam);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDroppedFrames)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPacketsSent)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTargetBitrate)) ||
         !ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
@@ -402,17 +402,17 @@ struct ParamTraits<mozilla::dom::RTCMedi
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mStreamIdentifier);
     WriteParam(aMsg, aParam.mTrackIds);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mStreamIdentifier)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTrackIds)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
     }
 
     return true;
@@ -426,17 +426,17 @@ struct ParamTraits<mozilla::dom::RTCTran
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mBytesReceived);
     WriteParam(aMsg, aParam.mBytesSent);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
         !ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
     }
 
     return true;
@@ -462,17 +462,17 @@ struct ParamTraits<mozilla::dom::RTCMedi
     WriteParam(aMsg, aParam.mFramesReceived);
     WriteParam(aMsg, aParam.mFramesSent);
     WriteParam(aMsg, aParam.mRemoteSource);
     WriteParam(aMsg, aParam.mSsrcIds);
     WriteParam(aMsg, aParam.mTrackIdentifier);
     WriteRTCStats(aMsg, aParam);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mAudioLevel)) ||
         !ReadParam(aMsg, aIter, &(aResult->mEchoReturnLoss)) ||
         !ReadParam(aMsg, aIter, &(aResult->mEchoReturnLossEnhancement)) ||
         !ReadParam(aMsg, aIter, &(aResult->mFrameHeight)) ||
         !ReadParam(aMsg, aIter, &(aResult->mFrameWidth)) ||
         !ReadParam(aMsg, aIter, &(aResult->mFramesCorrupted)) ||
         !ReadParam(aMsg, aIter, &(aResult->mFramesDecoded)) ||
--- a/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
+++ b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
@@ -92,17 +92,17 @@ struct ParamTraits<nsIMobileCallForwardi
     aParam->GetTimeSeconds(&pShort);
     WriteParam(aMsg, pShort);
 
     aParam->GetServiceClass(&pShort);
     WriteParam(aMsg, pShort);
   }
 
   // Function to de-serialize a MobileCallForwardingOptions.
-  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message *aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if is the null pointer we have transfered.
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) {
       return false;
     }
 
     if (isNull) {
@@ -171,17 +171,17 @@ struct ParamTraits<nsIMobileNetworkInfo*
     aParam->GetState(pString);
     WriteParam(aMsg, pString);
 
     // We release the ref here given that ipdl won't handle reference counting.
     aParam->Release();
   }
 
   // Function to de-serialize a MobileNetworkInfo.
-  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message *aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if is the null pointer we have transfered.
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) {
       return false;
     }
 
     if (isNull) {
@@ -258,17 +258,17 @@ struct ParamTraits<nsIMobileCellInfo*>
     aParam->GetCdmaNetworkId(&pLong);
     WriteParam(aMsg, pLong);
 
     // We release the ref here given that ipdl won't handle reference counting.
     aParam->Release();
   }
 
   // Function to de-serialize a MobileCellInfo.
-  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message *aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if is the null pointer we have transfered.
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) {
       return false;
     }
 
     if (isNull) {
@@ -373,17 +373,17 @@ struct ParamTraits<nsIMobileConnectionIn
       WriteParam(aMsg, pInt32);
     }
 
     // We release the ref here given that ipdl won't handle reference counting.
     aParam->Release();
   }
 
   // Function to de-serialize a MobileConectionInfo.
-  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if is the null pointer we have transfered.
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) {
       return false;
     }
 
     if (isNull) {
@@ -536,17 +536,17 @@ struct ParamTraits<MozCallForwardingOpti
       WriteParam(aMsg, isNull);
       if (!isNull) {
         WriteParam(aMsg, aParam.mServiceClass.Value().Value());
       }
     }
   }
 
   // Function to de-serialize a MozCallForwardingOptions.
-  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  static bool Read(const Message *aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool wasPassed = false;
     bool isNull = false;
 
     // Read mActive
     if (!ReadParam(aMsg, aIter, &wasPassed)) {
       return false;
     }
--- a/dom/plugins/ipc/NPEventAndroid.h
+++ b/dom/plugins/ipc/NPEventAndroid.h
@@ -32,17 +32,17 @@ struct ParamTraits<mozilla::plugins::NPR
 {
     typedef mozilla::plugins::NPRemoteEvent paramType;
 
     static void Write(Message* aMsg, const paramType& aParam)
     {
         aMsg->WriteBytes(&aParam, sizeof(paramType));
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         const char* bytes = 0;
 
         if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) {
             return false;
         }
 
         memcpy(aResult, bytes, sizeof(paramType));
--- a/dom/plugins/ipc/NPEventOSX.h
+++ b/dom/plugins/ipc/NPEventOSX.h
@@ -77,17 +77,17 @@ struct ParamTraits<mozilla::plugins::NPR
                 break;
             default:
                 NS_NOTREACHED("Attempted to serialize unknown event type.");
                 return;
         }
         aMsg->WriteDouble(aParam.contentsScaleFactor);
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         int type = 0;
         if (!aMsg->ReadInt(aIter, &type)) {
             return false;
         }
         aResult->event.type = static_cast<NPCocoaEventType>(type);
 
         if (!aMsg->ReadUInt32(aIter, &aResult->event.version)) {
--- a/dom/plugins/ipc/NPEventUnix.h
+++ b/dom/plugins/ipc/NPEventUnix.h
@@ -50,17 +50,17 @@ struct ParamTraits<mozilla::plugins::NPR
 {
     typedef mozilla::plugins::NPRemoteEvent paramType;
 
     static void Write(Message* aMsg, const paramType& aParam)
     {
         aMsg->WriteBytes(&aParam, sizeof(paramType));
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         const char* bytes = 0;
 
         if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) {
             return false;
         }
 
         memcpy(aResult, bytes, sizeof(paramType));
--- a/dom/plugins/ipc/NPEventWindows.h
+++ b/dom/plugins/ipc/NPEventWindows.h
@@ -125,17 +125,17 @@ struct ParamTraits<mozilla::plugins::NPR
                 // entirely.
                 paramCopy.event.event = WM_NULL;
                 break;
         }
 
         aMsg->WriteBytes(&paramCopy, sizeof(paramType));
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         const char* bytes = 0;
 
         if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) {
             return false;
         }
         memcpy(aResult, bytes, sizeof(paramType));
 
--- a/dom/plugins/ipc/PluginMessageUtils.h
+++ b/dom/plugins/ipc/PluginMessageUtils.h
@@ -275,17 +275,17 @@ struct ParamTraits<NPRect>
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.top);
     WriteParam(aMsg, aParam.left);
     WriteParam(aMsg, aParam.bottom);
     WriteParam(aMsg, aParam.right);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint16_t top, left, bottom, right;
     if (ReadParam(aMsg, aIter, &top) &&
         ReadParam(aMsg, aIter, &left) &&
         ReadParam(aMsg, aIter, &bottom) &&
         ReadParam(aMsg, aIter, &right)) {
       aResult->top = top;
       aResult->left = left;
@@ -308,17 +308,17 @@ struct ParamTraits<NPWindowType>
 {
   typedef NPWindowType paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aMsg->WriteInt16(int16_t(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     int16_t result;
     if (aMsg->ReadInt16(aIter, &result)) {
       *aResult = paramType(result);
       return true;
     }
     return false;
   }
@@ -347,17 +347,17 @@ struct ParamTraits<mozilla::plugins::NPR
     aMsg->WriteULong(aParam.visualID);
     aMsg->WriteULong(aParam.colormap);
 #endif
 #if defined(XP_MACOSX)
     aMsg->WriteDouble(aParam.contentsScaleFactor);
 #endif
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint64_t window;
     int32_t x, y;
     uint32_t width, height;
     NPRect clipRect;
     NPWindowType type;
     if (!(aMsg->ReadUInt64(aIter, &window) &&
           ReadParam(aMsg, aIter, &x) &&
@@ -438,17 +438,17 @@ struct ParamTraits<NPNSString*>
     } else {
       UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
       ::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
       aMsg->WriteBytes(buffer, length * sizeof(UniChar));
       free(buffer);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool haveString = false;
     if (!aMsg->ReadBool(aIter, &haveString)) {
       return false;
     }
     if (!haveString) {
       *aResult = nullptr;
       return true;
@@ -502,17 +502,17 @@ struct ParamTraits<NSCursorInfo>
     }
 
     uint8_t* buffer = (uint8_t*)moz_xmalloc(dataLength);
     memcpy(buffer, aParam.GetCustomImageData(), dataLength);
     aMsg->WriteBytes(buffer, dataLength);
     free(buffer);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     NSCursorInfo::Type type;
     if (!aMsg->ReadInt(aIter, (int*)&type)) {
       return false;
     }
 
     nscoord hotSpotX, hotSpotY;
     if (!ReadParam(aMsg, aIter, &hotSpotX) ||
@@ -561,17 +561,17 @@ struct ParamTraits<NSCursorInfo>
 #else
 template<>
 struct ParamTraits<NSCursorInfo>
 {
   typedef NSCursorInfo paramType;
   static void Write(Message* aMsg, const paramType& aParam) {
     NS_RUNTIMEABORT("NSCursorInfo isn't meaningful on this platform");
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
     NS_RUNTIMEABORT("NSCursorInfo isn't meaningful on this platform");
     return false;
   }
 };
 #endif // #ifdef XP_MACOSX
 
 template <>
 struct ParamTraits<mozilla::plugins::IPCByteRange>
@@ -579,17 +579,17 @@ struct ParamTraits<mozilla::plugins::IPC
   typedef mozilla::plugins::IPCByteRange paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.offset);
     WriteParam(aMsg, aParam.length);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     paramType p;
     if (ReadParam(aMsg, aIter, &p.offset) &&
         ReadParam(aMsg, aIter, &p.length)) {
       *aResult = p;
       return true;
     }
     return false;
@@ -601,17 +601,17 @@ struct ParamTraits<NPNVariable>
 {
   typedef NPNVariable paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, int(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     int intval;
     if (ReadParam(aMsg, aIter, &intval)) {
       *aResult = paramType(intval);
       return true;
     }
     return false;
   }
@@ -622,17 +622,17 @@ struct ParamTraits<NPNURLVariable>
 {
   typedef NPNURLVariable paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, int(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     int intval;
     if (ReadParam(aMsg, aIter, &intval)) {
       switch (intval) {
       case NPNURLVCookie:
       case NPNURLVProxy:
         *aResult = paramType(intval);
         return true;
@@ -648,17 +648,17 @@ struct ParamTraits<NPCoordinateSpace>
 {
   typedef NPCoordinateSpace paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, int32_t(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     int32_t intval;
     if (ReadParam(aMsg, aIter, &intval)) {
       switch (intval) {
       case NPCoordinateSpacePlugin:
       case NPCoordinateSpaceWindow:
       case NPCoordinateSpaceFlippedWindow:
       case NPCoordinateSpaceScreen:
--- a/dom/telephony/ipc/TelephonyIPCSerializer.h
+++ b/dom/telephony/ipc/TelephonyIPCSerializer.h
@@ -78,17 +78,17 @@ struct ParamTraits<nsITelephonyCallInfo*
 
     WriteParam(aMsg, isOutgoing);
     WriteParam(aMsg, isEmergency);
     WriteParam(aMsg, isConference);
     WriteParam(aMsg, isSwitchable);
     WriteParam(aMsg, isMergeable);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     // Check if is the null pointer we have transfered.
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) {
       return false;
     }
 
     if (isNull) {
--- a/gfx/ipc/D3DMessageUtils.cpp
+++ b/gfx/ipc/D3DMessageUtils.cpp
@@ -48,17 +48,17 @@ ParamTraits<DxgiAdapterDesc>::Write(Mess
   WriteParam(aMsg, aParam.AdapterLuid.LowPart);
   WriteParam(aMsg, aParam.AdapterLuid.HighPart);
 #else
   MOZ_ASSERT_UNREACHABLE("DxgiAdapterDesc is Windows-only");
 #endif
 }
 
 bool
-ParamTraits<DxgiAdapterDesc>::Read(const Message* aMsg, void** aIter, paramType* aResult)
+ParamTraits<DxgiAdapterDesc>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
 {
 #if defined(XP_WIN)
   const char* description = nullptr;
   if (!aMsg->ReadBytes(aIter, &description, sizeof(aResult->Description))) {
     return false;
   }
   memcpy(aResult->Description, description, sizeof(aResult->Description));
 
--- a/gfx/ipc/D3DMessageUtils.h
+++ b/gfx/ipc/D3DMessageUtils.h
@@ -35,14 +35,14 @@ struct DxgiAdapterDesc
 
 namespace IPC {
 
 template <>
 struct ParamTraits<DxgiAdapterDesc>
 {
   typedef DxgiAdapterDesc paramType;
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 } // namespace IPC
 
 #endif // _include_gfx_ipc_D3DMessageUtils_h__
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -49,17 +49,17 @@ struct ParamTraits<mozilla::gfx::Matrix>
     WriteParam(aMsg, aParam._11);
     WriteParam(aMsg, aParam._12);
     WriteParam(aMsg, aParam._21);
     WriteParam(aMsg, aParam._22);
     WriteParam(aMsg, aParam._31);
     WriteParam(aMsg, aParam._32);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (ReadParam(aMsg, aIter, &aResult->_11) &&
         ReadParam(aMsg, aIter, &aResult->_12) &&
         ReadParam(aMsg, aIter, &aResult->_21) &&
         ReadParam(aMsg, aIter, &aResult->_22) &&
         ReadParam(aMsg, aIter, &aResult->_31) &&
         ReadParam(aMsg, aIter, &aResult->_32))
       return true;
@@ -84,17 +84,17 @@ struct ParamTraits<mozilla::gfx::Matrix4
 #define Wr(_f)  WriteParam(msg, param. _f)
     Wr(_11); Wr(_12); Wr(_13); Wr(_14);
     Wr(_21); Wr(_22); Wr(_23); Wr(_24);
     Wr(_31); Wr(_32); Wr(_33); Wr(_34);
     Wr(_41); Wr(_42); Wr(_43); Wr(_44);
 #undef Wr
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
 #define Rd(_f)  ReadParam(msg, iter, &result-> _f)
     return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
             Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
             Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
             Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44));
 #undef Rd
   }
@@ -111,17 +111,17 @@ struct ParamTraits<mozilla::gfx::Matrix5
     Wr(_11); Wr(_12); Wr(_13); Wr(_14);
     Wr(_21); Wr(_22); Wr(_23); Wr(_24);
     Wr(_31); Wr(_32); Wr(_33); Wr(_34);
     Wr(_41); Wr(_42); Wr(_43); Wr(_44);
     Wr(_51); Wr(_52); Wr(_53); Wr(_54);
 #undef Wr
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
 #define Rd(_f)  ReadParam(msg, iter, &result-> _f)
     return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
             Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
             Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
             Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44) &&
             Rd(_51) && Rd(_52) && Rd(_53) && Rd(_54));
 #undef Rd
@@ -134,17 +134,17 @@ struct ParamTraits<gfxPoint>
   typedef gfxPoint paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.x);
     WriteParam(aMsg, aParam.y);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->x) &&
             ReadParam(aMsg, aIter, &aResult->y));
  }
 };
 
 template<>
 struct ParamTraits<gfxSize>
@@ -152,17 +152,17 @@ struct ParamTraits<gfxSize>
   typedef gfxSize paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.width);
     WriteParam(aMsg, aParam.height);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (ReadParam(aMsg, aIter, &aResult->width) &&
         ReadParam(aMsg, aIter, &aResult->height))
       return true;
 
     return false;
   }
 };
@@ -175,17 +175,17 @@ struct ParamTraits<gfxRect>
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.x);
     WriteParam(aMsg, aParam.y);
     WriteParam(aMsg, aParam.width);
     WriteParam(aMsg, aParam.height);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->x) &&
            ReadParam(aMsg, aIter, &aResult->y) &&
            ReadParam(aMsg, aIter, &aResult->width) &&
            ReadParam(aMsg, aIter, &aResult->height);
   }
 };
 
@@ -292,17 +292,17 @@ struct ParamTraits<mozilla::gfx::Color>
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.r);
     WriteParam(msg, param.g);
     WriteParam(msg, param.b);
     WriteParam(msg, param.a);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->r) &&
             ReadParam(msg, iter, &result->g) &&
             ReadParam(msg, iter, &result->b) &&
             ReadParam(msg, iter, &result->a));
   }
 };
 
@@ -312,17 +312,17 @@ struct ParamTraits<nsPoint>
   typedef nsPoint paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y));
   }
 };
 
 template<>
 struct ParamTraits<nsIntPoint>
@@ -330,17 +330,17 @@ struct ParamTraits<nsIntPoint>
   typedef nsIntPoint paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y));
   }
 };
 
 template<typename T>
 struct ParamTraits<mozilla::gfx::IntSizeTyped<T> >
@@ -348,17 +348,17 @@ struct ParamTraits<mozilla::gfx::IntSize
   typedef mozilla::gfx::IntSizeTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
 template<typename Region, typename Rect, typename Iter>
 struct RegionParamTraits
@@ -373,17 +373,17 @@ struct RegionParamTraits
       MOZ_RELEASE_ASSERT(!r.IsEmpty());
       WriteParam(msg, r);
     }
     // empty rects are sentinel values because nsRegions will never
     // contain them
     WriteParam(msg, Rect());
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     RegionBuilder<Region> builder;
     Rect rect;
     while (ReadParam(msg, iter, &rect)) {
       if (rect.IsEmpty()) {
         *result = builder.ToRegion();
         return true;
       }
@@ -407,83 +407,83 @@ struct ParamTraits<mozilla::gfx::IntSize
   typedef mozilla::gfx::IntSize paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
 template<class T>
 struct ParamTraits< mozilla::gfx::CoordTyped<T> >
 {
   typedef mozilla::gfx::CoordTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.value);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->value));
   }
 };
 
 template<class T>
 struct ParamTraits< mozilla::gfx::IntCoordTyped<T> >
 {
   typedef mozilla::gfx::IntCoordTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.value);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->value));
   }
 };
 
 template<class T, class U>
 struct ParamTraits< mozilla::gfx::ScaleFactor<T, U> >
 {
   typedef mozilla::gfx::ScaleFactor<T, U> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.scale);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->scale));
   }
 };
 
 template<class T, class U>
 struct ParamTraits< mozilla::gfx::ScaleFactors2D<T, U> >
 {
   typedef mozilla::gfx::ScaleFactors2D<T, U> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.xScale);
     WriteParam(msg, param.yScale);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->xScale) &&
             ReadParam(msg, iter, &result->yScale));
   }
 };
 
 template<class T>
 struct ParamTraits< mozilla::gfx::PointTyped<T> >
@@ -491,17 +491,17 @@ struct ParamTraits< mozilla::gfx::PointT
   typedef mozilla::gfx::PointTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y));
   }
 };
 
 template<class F, class T>
 struct ParamTraits< mozilla::gfx::Point3DTyped<F, T> >
@@ -510,17 +510,17 @@ struct ParamTraits< mozilla::gfx::Point3
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.z);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y) &&
             ReadParam(msg, iter, &result->z));
   }
 };
 
 template<class T>
@@ -529,17 +529,17 @@ struct ParamTraits< mozilla::gfx::IntPoi
   typedef mozilla::gfx::IntPointTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y));
   }
 };
 
 template<class T>
 struct ParamTraits< mozilla::gfx::SizeTyped<T> >
@@ -547,17 +547,17 @@ struct ParamTraits< mozilla::gfx::SizeTy
   typedef mozilla::gfx::SizeTyped<T> paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
 template<class T>
 struct ParamTraits< mozilla::gfx::RectTyped<T> >
@@ -567,17 +567,17 @@ struct ParamTraits< mozilla::gfx::RectTy
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y) &&
             ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
@@ -589,17 +589,17 @@ struct ParamTraits< mozilla::gfx::IntRec
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y) &&
             ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
@@ -611,17 +611,17 @@ struct ParamTraits<mozilla::gfx::Margin>
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.top);
     WriteParam(msg, param.right);
     WriteParam(msg, param.bottom);
     WriteParam(msg, param.left);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->top) &&
             ReadParam(msg, iter, &result->right) &&
             ReadParam(msg, iter, &result->bottom) &&
             ReadParam(msg, iter, &result->left));
   }
 };
 
@@ -633,17 +633,17 @@ struct ParamTraits< mozilla::gfx::Margin
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.top);
     WriteParam(msg, param.right);
     WriteParam(msg, param.bottom);
     WriteParam(msg, param.left);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->top) &&
             ReadParam(msg, iter, &result->right) &&
             ReadParam(msg, iter, &result->bottom) &&
             ReadParam(msg, iter, &result->left));
   }
 };
 
@@ -655,17 +655,17 @@ struct ParamTraits<nsRect>
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->x) &&
             ReadParam(msg, iter, &result->y) &&
             ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
@@ -685,17 +685,17 @@ struct ParamTraits<mozilla::layers::Fram
 // Helper class for reading bitfields.
 // If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>.
 template <typename ParamType>
 struct BitfieldHelper
 {
   // We need this helper because we can't get the address of a bitfield to
   // pass directly to ReadParam. So instead we read it into a temporary bool
   // and set the bitfield using a setter function
-  static bool ReadBoolForBitfield(const Message* aMsg, void** aIter,
+  static bool ReadBoolForBitfield(const Message* aMsg, PickleIterator* aIter,
         ParamType* aResult, void (ParamType::*aSetter)(bool))
   {
     bool value;
     if (ReadParam(aMsg, aIter, &value)) {
       (aResult->*aSetter)(value);
       return true;
     }
     return false;
@@ -730,17 +730,17 @@ struct ParamTraits<mozilla::layers::Fram
     WriteParam(aMsg, aParam.mPaintRequestTime);
     WriteParam(aMsg, aParam.mScrollUpdateType);
     WriteParam(aMsg, aParam.mIsRootContent);
     WriteParam(aMsg, aParam.mDoSmoothScroll);
     WriteParam(aMsg, aParam.mUseDisplayPortMargins);
     WriteParam(aMsg, aParam.mIsScrollInfoLayer);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mScrollId) &&
             ReadParam(aMsg, aIter, &aResult->mPresShellResolution) &&
             ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
             ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
             ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
             ReadParam(aMsg, aIter, &aResult->mScrollableRect) &&
             ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
@@ -773,17 +773,17 @@ struct ParamTraits<mozilla::layers::Scro
     WriteParam(aMsg, aParam.mScrollSnapTypeX);
     WriteParam(aMsg, aParam.mScrollSnapTypeY);
     WriteParam(aMsg, aParam.mScrollSnapIntervalX);
     WriteParam(aMsg, aParam.mScrollSnapIntervalY);
     WriteParam(aMsg, aParam.mScrollSnapDestination);
     WriteParam(aMsg, aParam.mScrollSnapCoordinates);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mScrollSnapTypeX) &&
             ReadParam(aMsg, aIter, &aResult->mScrollSnapTypeY) &&
             ReadParam(aMsg, aIter, &aResult->mScrollSnapIntervalX) &&
             ReadParam(aMsg, aIter, &aResult->mScrollSnapIntervalY) &&
             ReadParam(aMsg, aIter, &aResult->mScrollSnapDestination) &&
             ReadParam(aMsg, aIter, &aResult->mScrollSnapCoordinates));
   }
@@ -795,17 +795,17 @@ struct ParamTraits<mozilla::layers::Laye
   typedef mozilla::layers::LayerClip paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mClipRect);
     WriteParam(aMsg, aParam.mMaskLayerIndex);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mClipRect) &&
             ReadParam(aMsg, aIter, &aResult->mMaskLayerIndex));
   }
 };
 
 template <>
 struct ParamTraits<mozilla::layers::ScrollMetadata>
@@ -825,27 +825,27 @@ struct ParamTraits<mozilla::layers::Scro
     WriteParam(aMsg, aParam.mScrollClip);
     WriteParam(aMsg, aParam.mHasScrollgrab);
     WriteParam(aMsg, aParam.mAllowVerticalScrollWithWheel);
     WriteParam(aMsg, aParam.mIsLayersIdRoot);
     WriteParam(aMsg, aParam.mUsesContainerScrolling);
     WriteParam(aMsg, aParam.mForceDisableApz);
   }
 
-  static bool ReadContentDescription(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool ReadContentDescription(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsCString str;
     if (!ReadParam(aMsg, aIter, &str)) {
       return false;
     }
     aResult->SetContentDescription(str);
     return true;
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mMetrics) &&
             ReadParam(aMsg, aIter, &aResult->mSnapInfo) &&
             ReadParam(aMsg, aIter, &aResult->mScrollParentId) &&
             ReadParam(aMsg, aIter, &aResult->mBackgroundColor) &&
             ReadContentDescription(aMsg, aIter, aResult) &&
             ReadParam(aMsg, aIter, &aResult->mLineScrollAmount) &&
             ReadParam(aMsg, aIter, &aResult->mPageScrollAmount) &&
@@ -867,17 +867,17 @@ struct ParamTraits<mozilla::layers::Text
   {
     WriteParam(aMsg, aParam.mParentBackend);
     WriteParam(aMsg, aParam.mMaxTextureSize);
     WriteParam(aMsg, aParam.mSupportsTextureBlitting);
     WriteParam(aMsg, aParam.mSupportsPartialUploads);
     WriteParam(aMsg, aParam.mSyncHandle);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool result = ReadParam(aMsg, aIter, &aResult->mParentBackend) &&
                   ReadParam(aMsg, aIter, &aResult->mMaxTextureSize) &&
                   ReadParam(aMsg, aIter, &aResult->mSupportsTextureBlitting) &&
                   ReadParam(aMsg, aIter, &aResult->mSupportsPartialUploads) &&
                   ReadParam(aMsg, aIter, &aResult->mSyncHandle);
     return result;
   }
@@ -889,17 +889,17 @@ struct ParamTraits<mozilla::layers::Text
   typedef mozilla::layers::TextureInfo paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mCompositableType);
     WriteParam(aMsg, aParam.mTextureFlags);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mCompositableType) &&
            ReadParam(aMsg, aIter, &aResult->mTextureFlags);
   }
 };
 
 template <>
 struct ParamTraits<mozilla::layers::CompositableType>
@@ -932,17 +932,17 @@ struct ParamTraits<mozilla::layers::Scro
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mLayersId);
     WriteParam(aMsg, aParam.mPresShellId);
     WriteParam(aMsg, aParam.mScrollId);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mLayersId) &&
             ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
             ReadParam(aMsg, aIter, &aResult->mScrollId));
   }
 };
 
 
@@ -954,17 +954,17 @@ struct ParamTraits<mozilla::layers::Zoom
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mAllowZoom);
     WriteParam(aMsg, aParam.mAllowDoubleTapZoom);
     WriteParam(aMsg, aParam.mMinZoom);
     WriteParam(aMsg, aParam.mMaxZoom);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mAllowZoom) &&
             ReadParam(aMsg, aIter, &aResult->mAllowDoubleTapZoom) &&
             ReadParam(aMsg, aIter, &aResult->mMinZoom) &&
             ReadParam(aMsg, aIter, &aResult->mMaxZoom));
   }
 };
 
@@ -977,17 +977,17 @@ struct ParamTraits<mozilla::layers::Even
   {
     WriteParam(aMsg, aParam.mHitRegion);
     WriteParam(aMsg, aParam.mDispatchToContentHitRegion);
     WriteParam(aMsg, aParam.mNoActionRegion);
     WriteParam(aMsg, aParam.mHorizontalPanRegion);
     WriteParam(aMsg, aParam.mVerticalPanRegion);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mHitRegion) &&
             ReadParam(aMsg, aIter, &aResult->mDispatchToContentHitRegion) &&
             ReadParam(aMsg, aIter, &aResult->mNoActionRegion) &&
             ReadParam(aMsg, aIter, &aResult->mHorizontalPanRegion) &&
             ReadParam(aMsg, aIter, &aResult->mVerticalPanRegion));
   }
 };
@@ -1032,17 +1032,17 @@ struct ParamTraits<mozilla::gfx::Attribu
 #undef CASE_TYPE
 
         default:
           MOZ_CRASH("GFX: unhandled attribute type");
       }
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint32_t count;
     if (!ReadParam(aMsg, aIter, &count)) {
       return false;
     }
     for (uint32_t i = 0; i < count; i++) {
       mozilla::gfx::AttributeType type;
       if (!ReadParam(aMsg, aIter, &type)) {
@@ -1111,17 +1111,17 @@ struct ParamTraits<mozilla::gfx::FilterP
     WriteParam(aMsg, aParam.NumberOfInputs());
     for (size_t i = 0; i < aParam.NumberOfInputs(); i++) {
       WriteParam(aMsg, aParam.InputPrimitiveIndex(i));
       WriteParam(aMsg, aParam.InputColorSpace(i));
     }
     WriteParam(aMsg, aParam.Attributes());
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     mozilla::gfx::PrimitiveType type;
     mozilla::gfx::IntRect primitiveSubregion;
     mozilla::gfx::IntRect filterSpaceBounds;
     bool isTainted = false;
     mozilla::gfx::ColorSpace outputColorSpace;
     size_t numberOfInputs = 0;
     if (!ReadParam(aMsg, aIter, &type) ||
@@ -1159,17 +1159,17 @@ struct ParamTraits<mozilla::gfx::FilterD
 {
   typedef mozilla::gfx::FilterDescription paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mPrimitives);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mPrimitives));
   }
 };
 
 typedef mozilla::layers::GeckoContentController::APZStateChange APZStateChange;
 
 template <>
@@ -1205,17 +1205,17 @@ struct ParamTraits<mozilla::layers::Asyn
     WriteParam(aMsg, aParam.mViewId);
     WriteParam(aMsg, aParam.mPresShellId);
     WriteParam(aMsg, aParam.mDragStartSequenceNumber);
     WriteParam(aMsg, aParam.mScrollbarDragOffset);
     WriteParam(aMsg, aParam.mScrollTrack);
     WriteParam(aMsg, aParam.mDirection);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mViewId) &&
             ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
             ReadParam(aMsg, aIter, &aResult->mDragStartSequenceNumber) &&
             ReadParam(aMsg, aIter, &aResult->mScrollbarDragOffset) &&
             ReadParam(aMsg, aIter, &aResult->mScrollTrack) &&
             ReadParam(aMsg, aIter, &aResult->mDirection));
   }
--- a/gfx/layers/apz/testutil/APZTestData.h
+++ b/gfx/layers/apz/testutil/APZTestData.h
@@ -138,17 +138,17 @@ struct ParamTraits<mozilla::layers::APZT
   typedef mozilla::layers::APZTestData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mPaints);
     WriteParam(aMsg, aParam.mRepaintRequests);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mPaints) &&
             ReadParam(aMsg, aIter, &aResult->mRepaintRequests));
   }
 };
 
 template <>
 struct ParamTraits<mozilla::layers::APZTestData::ScrollFrameData>
--- a/gfx/layers/composite/FrameUniformityData.h
+++ b/gfx/layers/composite/FrameUniformityData.h
@@ -57,17 +57,17 @@ struct ParamTraits<mozilla::layers::Fram
 {
   typedef mozilla::layers::FrameUniformityData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mUniformities);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ParamTraitsStd<std::map<uintptr_t,float>>::Read(aMsg, aIter, &aResult->mUniformities);
   }
 };
 
 } // namespace IPC
 
 #endif // mozilla_layers_FrameUniformityData_h_
--- a/gfx/layers/ipc/FenceUtils.cpp
+++ b/gfx/layers/ipc/FenceUtils.cpp
@@ -28,17 +28,17 @@ ParamTraits<FenceHandle>::Write(Message*
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   RefPtr<FenceHandle::FdObj> fence = handle.GetAndResetFdObj();
   aMsg->WriteFileDescriptor(base::FileDescriptor(fence->GetAndResetFd(), true));
 #endif
 }
 
 bool
 ParamTraits<FenceHandle>::Read(const Message* aMsg,
-                               void** aIter, paramType* aResult)
+                               PickleIterator* aIter, paramType* aResult)
 {
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   base::FileDescriptor fd;
   if (aMsg->ReadFileDescriptor(aIter, &fd)) {
     aResult->Merge(FenceHandle(new FenceHandle::FdObj(fd.fd)));
   }
 #endif
   return true;
--- a/gfx/layers/ipc/FenceUtils.h
+++ b/gfx/layers/ipc/FenceUtils.h
@@ -71,14 +71,14 @@ private:
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::layers::FenceHandle> {
   typedef mozilla::layers::FenceHandle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 } // namespace IPC
 
 #endif // IPC_FencerUtils_h
--- a/gfx/layers/ipc/GonkNativeHandleUtils.cpp
+++ b/gfx/layers/ipc/GonkNativeHandleUtils.cpp
@@ -27,17 +27,17 @@ ParamTraits<GonkNativeHandle>::Write(Mes
 
   for (size_t i = 0; i < static_cast<size_t>(nativeHandle->numFds); ++i) {
     aMsg->WriteFileDescriptor(base::FileDescriptor(nativeHandle->data[i], true));
   }
 }
 
 bool
 ParamTraits<GonkNativeHandle>::Read(const Message* aMsg,
-                               void** aIter, paramType* aResult)
+                               PickleIterator* aIter, paramType* aResult)
 {
   size_t nbytes;
   const char* data;
   if (!aMsg->ReadSize(aIter, &nbytes) ||
       !aMsg->ReadBytes(aIter, &data, nbytes)) {
     return false;
   }
 
--- a/gfx/layers/ipc/GonkNativeHandleUtils.h
+++ b/gfx/layers/ipc/GonkNativeHandleUtils.h
@@ -15,22 +15,22 @@
 namespace IPC {
 
 #ifdef MOZ_WIDGET_GONK
 template <>
 struct ParamTraits<mozilla::layers::GonkNativeHandle> {
   typedef mozilla::layers::GonkNativeHandle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 #else
 template <>
 struct ParamTraits<mozilla::layers::GonkNativeHandle> {
   typedef mozilla::layers::GonkNativeHandle paramType;
   static void Write(Message*, const paramType&) {}
-  static bool Read(const Message*, void**, paramType*) { return false; }
+  static bool Read(const Message*, PickleIterator*, paramType*) { return false; }
 };
 #endif
 
 } // namespace IPC
 
 #endif // IPC_GonkNativeHandleUtils_h
--- a/gfx/layers/ipc/ShadowLayerUtils.h
+++ b/gfx/layers/ipc/ShadowLayerUtils.h
@@ -45,33 +45,33 @@ struct GrallocBufferRef {
 
 namespace IPC {
 
 #if !defined(MOZ_HAVE_SURFACEDESCRIPTORX11)
 template <>
 struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
   typedef mozilla::layers::SurfaceDescriptorX11 paramType;
   static void Write(Message*, const paramType&) {}
-  static bool Read(const Message*, void**, paramType*) { return false; }
+  static bool Read(const Message*, PickleIterator*, paramType*) { return false; }
 };
 #endif  // !defined(MOZ_HAVE_XSURFACEDESCRIPTORX11)
 
 #if !defined(MOZ_HAVE_SURFACEDESCRIPTORGRALLOC)
 template <>
 struct ParamTraits<mozilla::layers::MagicGrallocBufferHandle> {
   typedef mozilla::layers::MagicGrallocBufferHandle paramType;
   static void Write(Message*, const paramType&) {}
-  static bool Read(const Message*, void**, paramType*) { return false; }
+  static bool Read(const Message*, PickleIterator*, paramType*) { return false; }
 };
 
 template <>
 struct ParamTraits<mozilla::layers::GrallocBufferRef> {
   typedef mozilla::layers::GrallocBufferRef paramType;
   static void Write(Message*, const paramType&) {}
-  static bool Read(const Message*, void**, paramType*) { return false; }
+  static bool Read(const Message*, PickleIterator*, paramType*) { return false; }
 };
 #endif  // !defined(MOZ_HAVE_XSURFACEDESCRIPTORGRALLOC)
 
 template <>
 struct ParamTraits<mozilla::ScreenRotation>
   : public ContiguousEnumSerializer<
              mozilla::ScreenRotation,
              mozilla::ROTATION_0,
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -44,17 +44,17 @@ void
 ParamTraits<GrallocBufferRef>::Write(Message* aMsg,
                                      const paramType& aParam)
 {
   aMsg->WriteInt(aParam.mOwner);
   aMsg->WriteInt64(aParam.mKey);
 }
 
 bool
-ParamTraits<GrallocBufferRef>::Read(const Message* aMsg, void** aIter,
+ParamTraits<GrallocBufferRef>::Read(const Message* aMsg, PickleIterator* aIter,
                                     paramType* aParam)
 {
   int owner;
   int64_t index;
   if (!aMsg->ReadInt(aIter, &owner) ||
       !aMsg->ReadInt64(aIter, &index)) {
     printf_stderr("ParamTraits<GrallocBufferRef>::Read() failed to read a message\n");
     return false;
@@ -104,17 +104,17 @@ ParamTraits<MagicGrallocBufferHandle>::W
     // synchonously and the parent-side buffer can only be dropped if
     // there's a crash.
     aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false));
   }
 }
 
 bool
 ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg,
-                                            void** aIter, paramType* aResult)
+                                            PickleIterator* aIter, paramType* aResult)
 {
   MOZ_ASSERT(!aResult->mGraphicBuffer.get());
   MOZ_ASSERT(aResult->mRef.mOwner == 0);
   MOZ_ASSERT(aResult->mRef.mKey == -1);
 
   size_t nbytes;
   const char* data;
   int owner;
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
@@ -74,22 +74,22 @@ android::sp<android::GraphicBuffer> GetG
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::layers::MagicGrallocBufferHandle> {
   typedef mozilla::layers::MagicGrallocBufferHandle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 template<>
 struct ParamTraits<mozilla::layers::GrallocBufferRef> {
   typedef mozilla::layers::GrallocBufferRef paramType;
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 
 } // namespace IPC
 
 #endif  // mozilla_layers_ShadowLayerUtilsGralloc_h
--- a/gfx/layers/ipc/ShadowLayerUtilsX11.h
+++ b/gfx/layers/ipc/ShadowLayerUtilsX11.h
@@ -66,17 +66,17 @@ struct ParamTraits<mozilla::layers::Surf
 
   static void Write(Message* aMsg, const paramType& aParam) {
     WriteParam(aMsg, aParam.mId);
     WriteParam(aMsg, aParam.mSize);
     WriteParam(aMsg, aParam.mFormat);
     WriteParam(aMsg, aParam.mGLXPixmap);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
     return (ReadParam(aMsg, aIter, &aResult->mId) &&
             ReadParam(aMsg, aIter, &aResult->mSize) &&
             ReadParam(aMsg, aIter, &aResult->mFormat) &&
             ReadParam(aMsg, aIter, &aResult->mGLXPixmap)
             );
   }
 };
 
--- a/gfx/vr/ipc/VRMessageUtils.h
+++ b/gfx/vr/ipc/VRMessageUtils.h
@@ -32,17 +32,17 @@ struct ParamTraits<mozilla::gfx::VRDevic
   typedef mozilla::gfx::VRDeviceUpdate paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mDeviceInfo);
     WriteParam(aMsg, aParam.mSensorState);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mDeviceInfo)) ||
         !ReadParam(aMsg, aIter, &(aResult->mSensorState))) {
       return false;
     }
     return true;
   }
 };
@@ -53,17 +53,17 @@ struct ParamTraits<mozilla::gfx::VRSenso
   typedef mozilla::gfx::VRSensorUpdate paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mDeviceID);
     WriteParam(aMsg, aParam.mSensorState);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mDeviceID)) ||
         !ReadParam(aMsg, aIter, &(aResult->mSensorState))) {
       return false;
     }
     return true;
   }
 };
@@ -87,17 +87,17 @@ struct ParamTraits<mozilla::gfx::VRDevic
       WriteParam(aMsg, aParam.mMaximumEyeFOV[i]);
       WriteParam(aMsg, aParam.mRecommendedEyeFOV[i]);
       WriteParam(aMsg, aParam.mEyeFOV[i]);
       WriteParam(aMsg, aParam.mEyeTranslation[i]);
       WriteParam(aMsg, aParam.mEyeProjectionMatrix[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDeviceID)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDeviceName)) ||
         !ReadParam(aMsg, aIter, &(aResult->mSupportedSensorBits)) ||
         !ReadParam(aMsg, aIter, &(aResult->mEyeResolution)) ||
         !ReadParam(aMsg, aIter, &(aResult->mScreenRect)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIsFakeScreen)) ||
@@ -145,17 +145,17 @@ struct ParamTraits<mozilla::gfx::VRHMDSe
     WriteParam(aMsg, aParam.linearVelocity[0]);
     WriteParam(aMsg, aParam.linearVelocity[1]);
     WriteParam(aMsg, aParam.linearVelocity[2]);
     WriteParam(aMsg, aParam.linearAcceleration[0]);
     WriteParam(aMsg, aParam.linearAcceleration[1]);
     WriteParam(aMsg, aParam.linearAcceleration[2]);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) ||
         !ReadParam(aMsg, aIter, &(aResult->inputFrameID)) ||
         !ReadParam(aMsg, aIter, &(aResult->flags)) ||
         !ReadParam(aMsg, aIter, &(aResult->orientation[0])) ||
         !ReadParam(aMsg, aIter, &(aResult->orientation[1])) ||
         !ReadParam(aMsg, aIter, &(aResult->orientation[2])) ||
         !ReadParam(aMsg, aIter, &(aResult->orientation[3])) ||
@@ -188,17 +188,17 @@ struct ParamTraits<mozilla::gfx::VRField
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.upDegrees);
     WriteParam(aMsg, aParam.rightDegrees);
     WriteParam(aMsg, aParam.downDegrees);
     WriteParam(aMsg, aParam.leftDegrees);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->upDegrees)) ||
         !ReadParam(aMsg, aIter, &(aResult->rightDegrees)) ||
         !ReadParam(aMsg, aIter, &(aResult->downDegrees)) ||
         !ReadParam(aMsg, aIter, &(aResult->leftDegrees))) {
       return false;
     }
 
--- a/ipc/chromium/src/base/histogram.cc
+++ b/ipc/chromium/src/base/histogram.cc
@@ -270,17 +270,17 @@ bool Histogram::DeserializeHistogramInfo
   int declared_min;
   int declared_max;
   size_t bucket_count;
   uint32_t range_checksum;
   int histogram_type;
   int pickle_flags;
   SampleSet sample;
 
-  void* iter = NULL;
+  PickleIterator iter(pickle);
   if (!pickle.ReadString(&iter, &histogram_name) ||
       !pickle.ReadInt(&iter, &declared_min) ||
       !pickle.ReadInt(&iter, &declared_max) ||
       !pickle.ReadSize(&iter, &bucket_count) ||
       !pickle.ReadUInt32(&iter, &range_checksum) ||
       !pickle.ReadInt(&iter, &histogram_type) ||
       !pickle.ReadInt(&iter, &pickle_flags) ||
       !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) {
@@ -781,17 +781,17 @@ bool Histogram::SampleSet::Serialize(Pic
 
   for (size_t index = 0; index < counts_.size(); ++index) {
     pickle->WriteInt(counts_[index]);
   }
 
   return true;
 }
 
-bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
+bool Histogram::SampleSet::Deserialize(PickleIterator* iter, const Pickle& pickle) {
   OffTheBooksMutexAutoLock locker(mutex_);
   DCHECK_EQ(counts_.size(), 0u);
   DCHECK_EQ(sum_, 0);
   DCHECK_EQ(redundant_count_, 0);
 
   size_t counts_size;
 
   if (!pickle.ReadInt64(iter, &sum_) ||
--- a/ipc/chromium/src/base/histogram.h
+++ b/ipc/chromium/src/base/histogram.h
@@ -50,16 +50,17 @@
 #include <map>
 #include <string>
 #include <vector>
 
 #include "base/time.h"
 #include "base/lock.h"
 
 class Pickle;
+class PickleIterator;
 
 namespace base {
 
 using mozilla::OffTheBooksMutex;
 using mozilla::OffTheBooksMutexAutoLock;
 
 //------------------------------------------------------------------------------
 // Provide easy general purpose histogram in a macro, just like stats counters.
@@ -356,17 +357,17 @@ class Histogram {
 
     // Accessor for histogram to make routine additions.
     void Accumulate(Sample value, Count count, size_t index);
 
     // Arithmetic manipulation of corresponding elements of the set.
     void Add(const SampleSet& other);
 
     bool Serialize(Pickle* pickle) const;
-    bool Deserialize(void** iter, const Pickle& pickle);
+    bool Deserialize(PickleIterator* iter, const Pickle& pickle);
 
     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
     //---------------- THREAD UNSAFE METHODS ----------------//
     //
     // The caller must hold |this.mutex_|, and must supply evidence by passing
     // a const reference to the relevant OffTheBooksMutexAutoLock used.
 
--- a/ipc/chromium/src/base/pickle.cc
+++ b/ipc/chromium/src/base/pickle.cc
@@ -88,23 +88,28 @@ struct Copier<T, size, true>
     // Check the first condition, as the second condition is already
     // known to be true, or we wouldn't be here.
     static_assert(MOZ_ALIGNOF(T*) == MOZ_ALIGNOF(void*),
                   "Pointers have different alignments");
     *dest = *(*reinterpret_cast<T**>(iter));
   }
 };
 
+} // anonymous namespace
+
 template<typename T>
-void CopyFromIter(T* dest, void** iter) {
+void
+PickleIterator::CopyFrom(T* dest) {
   static_assert(mozilla::IsPod<T>::value, "Copied type must be a POD type");
-  Copier<T, sizeof(T), (MOZ_ALIGNOF(T) <= sizeof(Pickle::memberAlignmentType))>::Copy(dest, iter);
+  Copier<T, sizeof(T), (MOZ_ALIGNOF(T) <= sizeof(Pickle::memberAlignmentType))>::Copy(dest, &iter_);
 }
 
-} // anonymous namespace
+PickleIterator::PickleIterator(const Pickle& pickle)
+   : iter_(const_cast<char*>(pickle.payload())) {
+}
 
 // Payload is sizeof(Pickle::memberAlignmentType) aligned.
 
 Pickle::Pickle()
     : header_(NULL),
       header_size_(sizeof(Header)),
       capacity_(0),
       variable_buffer_offset_(0) {
@@ -163,313 +168,278 @@ Pickle::~Pickle() {
 Pickle& Pickle::operator=(Pickle&& other) {
   std::swap(header_, other.header_);
   std::swap(header_size_, other.header_size_);
   std::swap(capacity_, other.capacity_);
   std::swap(variable_buffer_offset_, other.variable_buffer_offset_);
   return *this;
 }
 
-bool Pickle::ReadBool(void** iter, bool* result) const {
+bool Pickle::ReadBool(PickleIterator* iter, bool* result) const {
   DCHECK(iter);
 
   int tmp;
   if (!ReadInt(iter, &tmp))
     return false;
   DCHECK(0 == tmp || 1 == tmp);
   *result = tmp ? true : false;
   return true;
 }
 
-bool Pickle::ReadInt16(void** iter, int16_t* result) const {
+bool Pickle::ReadInt16(PickleIterator* iter, int16_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadUInt16(void** iter, uint16_t* result) const {
+bool Pickle::ReadUInt16(PickleIterator* iter, uint16_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadInt(void** iter, int* result) const {
+bool Pickle::ReadInt(PickleIterator* iter, int* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
 // Always written as a 64-bit value since the size for this type can
 // differ between architectures.
-bool Pickle::ReadLong(void** iter, long* result) const {
+bool Pickle::ReadLong(PickleIterator* iter, long* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   int64_t bigResult = 0;
   if (!IteratorHasRoomFor(*iter, sizeof(bigResult)))
     return false;
 
-  CopyFromIter(&bigResult, iter);
+  iter->CopyFrom(&bigResult);
   DCHECK(bigResult <= LONG_MAX && bigResult >= LONG_MIN);
   *result = static_cast<long>(bigResult);
 
   UpdateIter(iter, sizeof(bigResult));
   return true;
 }
 
 // Always written as a 64-bit value since the size for this type can
 // differ between architectures.
-bool Pickle::ReadULong(void** iter, unsigned long* result) const {
+bool Pickle::ReadULong(PickleIterator* iter, unsigned long* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   uint64_t bigResult = 0;
   if (!IteratorHasRoomFor(*iter, sizeof(bigResult)))
     return false;
 
-  CopyFromIter(&bigResult, iter);
+  iter->CopyFrom(&bigResult);
   DCHECK(bigResult <= ULONG_MAX);
   *result = static_cast<unsigned long>(bigResult);
 
   UpdateIter(iter, sizeof(bigResult));
   return true;
 }
 
-bool Pickle::ReadLength(void** iter, int* result) const {
+bool Pickle::ReadLength(PickleIterator* iter, int* result) const {
   if (!ReadInt(iter, result))
     return false;
   return ((*result) >= 0);
 }
 
 // Always written as a 64-bit value since the size for this type can
 // differ between architectures.
-bool Pickle::ReadSize(void** iter, size_t* result) const {
+bool Pickle::ReadSize(PickleIterator* iter, size_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   uint64_t bigResult = 0;
   if (!IteratorHasRoomFor(*iter, sizeof(bigResult)))
     return false;
 
-  CopyFromIter(&bigResult, iter);
+  iter->CopyFrom(&bigResult);
   DCHECK(bigResult <= std::numeric_limits<size_t>::max());
   *result = static_cast<size_t>(bigResult);
 
   UpdateIter(iter, sizeof(bigResult));
   return true;
 }
 
-bool Pickle::ReadInt32(void** iter, int32_t* result) const {
+bool Pickle::ReadInt32(PickleIterator* iter, int32_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadUInt32(void** iter, uint32_t* result) const {
+bool Pickle::ReadUInt32(PickleIterator* iter, uint32_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadInt64(void** iter, int64_t* result) const {
+bool Pickle::ReadInt64(PickleIterator* iter, int64_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadUInt64(void** iter, uint64_t* result) const {
+bool Pickle::ReadUInt64(PickleIterator* iter, uint64_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadDouble(void** iter, double* result) const {
+bool Pickle::ReadDouble(PickleIterator* iter, double* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
 // Always written as a 64-bit value since the size for this type can
 // differ between architectures.
-bool Pickle::ReadIntPtr(void** iter, intptr_t* result) const {
+bool Pickle::ReadIntPtr(PickleIterator* iter, intptr_t* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   int64_t bigResult = 0;
   if (!IteratorHasRoomFor(*iter, sizeof(bigResult)))
     return false;
 
-  CopyFromIter(&bigResult, iter);
+  iter->CopyFrom(&bigResult);
   DCHECK(bigResult <= std::numeric_limits<intptr_t>::max() && bigResult >= std::numeric_limits<intptr_t>::min());
   *result = static_cast<intptr_t>(bigResult);
 
   UpdateIter(iter, sizeof(bigResult));
   return true;
 }
 
-bool Pickle::ReadUnsignedChar(void** iter, unsigned char* result) const {
+bool Pickle::ReadUnsignedChar(PickleIterator* iter, unsigned char* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!IteratorHasRoomFor(*iter, sizeof(*result)))
     return false;
 
-  CopyFromIter(result, iter);
+  iter->CopyFrom(result);
 
   UpdateIter(iter, sizeof(*result));
   return true;
 }
 
-bool Pickle::ReadString(void** iter, std::string* result) const {
+bool Pickle::ReadString(PickleIterator* iter, std::string* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   int len;
   if (!ReadLength(iter, &len))
     return false;
   if (!IteratorHasRoomFor(*iter, len))
     return false;
 
-  char* chars = reinterpret_cast<char*>(*iter);
+  char* chars = reinterpret_cast<char*>(iter->iter_);
   result->assign(chars, len);
 
   UpdateIter(iter, len);
   return true;
 }
 
-bool Pickle::ReadWString(void** iter, std::wstring* result) const {
+bool Pickle::ReadWString(PickleIterator* iter, std::wstring* result) const {
   DCHECK(iter);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   int len;
   if (!ReadLength(iter, &len))
     return false;
   // Avoid integer multiplication overflow.
   if (len > INT_MAX / static_cast<int>(sizeof(wchar_t)))
     return false;
   if (!IteratorHasRoomFor(*iter, len * sizeof(wchar_t)))
     return false;
 
-  wchar_t* chars = reinterpret_cast<wchar_t*>(*iter);
+  wchar_t* chars = reinterpret_cast<wchar_t*>(iter->iter_);
   result->assign(chars, len);
 
   UpdateIter(iter, len * sizeof(wchar_t));
   return true;
 }
 
-bool Pickle::ReadBytes(void** iter, const char** data, int length,
+bool Pickle::ReadBytes(PickleIterator* iter, const char** data, int length,
                        uint32_t alignment) const {
   DCHECK(iter);
   DCHECK(data);
   DCHECK(alignment == 4 || alignment == 8);
   DCHECK(intptr_t(header_) % alignment == 0);
 
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
-
-  uint32_t paddingLen = intptr_t(*iter) % alignment;
+  uint32_t paddingLen = intptr_t(iter->iter_) % alignment;
   if (paddingLen) {
 #ifdef DEBUG
     {
-      const char* padding = static_cast<const char*>(*iter);
+      const char* padding = static_cast<const char*>(iter->iter_);
       for (uint32_t i = 0; i < paddingLen; i++) {
         DCHECK(*(padding + i) == kBytePaddingMarker);
       }
     }
 #endif
     length += paddingLen;
   }
 
   if (!IteratorHasRoomFor(*iter, length))
     return false;
 
-  *data = static_cast<const char*>(*iter) + paddingLen;
+  *data = static_cast<const char*>(iter->iter_) + paddingLen;
   DCHECK(intptr_t(*data) % alignment == 0);
 
   UpdateIter(iter, length);
   return true;
 }
 
-bool Pickle::ReadData(void** iter, const char** data, int* length) const {
+bool Pickle::ReadData(PickleIterator* iter, const char** data, int* length) const {
   DCHECK(iter);
   DCHECK(data);
   DCHECK(length);
-  if (!*iter)
-    *iter = const_cast<char*>(payload());
 
   if (!ReadLength(iter, length))
     return false;
 
   return ReadBytes(iter, data, *length);
 }
 
 char* Pickle::BeginWrite(uint32_t length, uint32_t alignment) {
--- a/ipc/chromium/src/base/pickle.h
+++ b/ipc/chromium/src/base/pickle.h
@@ -10,16 +10,31 @@
 #include <string>
 
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/string16.h"
 
 #include "mozilla/Attributes.h"
 
+class Pickle;
+
+class PickleIterator {
+public:
+  explicit PickleIterator(const Pickle& pickle);
+
+private:
+  friend class Pickle;
+
+  template<typename T>
+  void CopyFrom(T* dest);
+
+  void* iter_;
+};
+
 // This class provides facilities for basic binary value packing and unpacking.
 //
 // The Pickle class supports appending primitive values (ints, strings, etc.)
 // to a pickle instance.  The Pickle instance grows its internal memory buffer
 // dynamically to hold the sequence of primitive values.   The internal memory
 // buffer is exposed as the "data" of the Pickle.  This "data" can be passed
 // to a Pickle object to initialize it for reading.
 //
@@ -77,40 +92,44 @@ class Pickle {
 
   // Returns the data for this Pickle.
   const void* data() const { return header_; }
 
   // Methods for reading the payload of the Pickle.  To read from the start of
   // the Pickle, initialize *iter to NULL.  If successful, these methods return
   // true.  Otherwise, false is returned to indicate that the result could not
   // be extracted.
-  MOZ_MUST_USE bool ReadBool(void** iter, bool* result) const;
-  MOZ_MUST_USE bool ReadInt16(void** iter, int16_t* result) const;
-  MOZ_MUST_USE bool ReadUInt16(void** iter, uint16_t* result) const;
-  MOZ_MUST_USE bool ReadShort(void** iter, short* result) const;
-  MOZ_MUST_USE bool ReadInt(void** iter, int* result) const;
-  MOZ_MUST_USE bool ReadLong(void** iter, long* result) const;
-  MOZ_MUST_USE bool ReadULong(void** iter, unsigned long* result) const;
-  MOZ_MUST_USE bool ReadSize(void** iter, size_t* result) const;
-  MOZ_MUST_USE bool ReadInt32(void** iter, int32_t* result) const;
-  MOZ_MUST_USE bool ReadUInt32(void** iter, uint32_t* result) const;
-  MOZ_MUST_USE bool ReadInt64(void** iter, int64_t* result) const;
-  MOZ_MUST_USE bool ReadUInt64(void** iter, uint64_t* result) const;
-  MOZ_MUST_USE bool ReadDouble(void** iter, double* result) const;
-  MOZ_MUST_USE bool ReadIntPtr(void** iter, intptr_t* result) const;
-  MOZ_MUST_USE bool ReadUnsignedChar(void** iter, unsigned char* result) const;
-  MOZ_MUST_USE bool ReadString(void** iter, std::string* result) const;
-  MOZ_MUST_USE bool ReadWString(void** iter, std::wstring* result) const;
-  MOZ_MUST_USE bool ReadData(void** iter, const char** data, int* length) const;
-  MOZ_MUST_USE bool ReadBytes(void** iter, const char** data, int length,
+  MOZ_MUST_USE bool ReadBool(PickleIterator* iter, bool* result) const;
+  MOZ_MUST_USE bool ReadInt16(PickleIterator* iter, int16_t* result) const;
+  MOZ_MUST_USE bool ReadUInt16(PickleIterator* iter, uint16_t* result) const;
+  MOZ_MUST_USE bool ReadShort(PickleIterator* iter, short* result) const;
+  MOZ_MUST_USE bool ReadInt(PickleIterator* iter, int* result) const;
+  MOZ_MUST_USE bool ReadLong(PickleIterator* iter, long* result) const;
+  MOZ_MUST_USE bool ReadULong(PickleIterator* iter, unsigned long* result) const;
+  MOZ_MUST_USE bool ReadSize(PickleIterator* iter, size_t* result) const;
+  MOZ_MUST_USE bool ReadInt32(PickleIterator* iter, int32_t* result) const;
+  MOZ_MUST_USE bool ReadUInt32(PickleIterator* iter, uint32_t* result) const;
+  MOZ_MUST_USE bool ReadInt64(PickleIterator* iter, int64_t* result) const;
+  MOZ_MUST_USE bool ReadUInt64(PickleIterator* iter, uint64_t* result) const;
+  MOZ_MUST_USE bool ReadDouble(PickleIterator* iter, double* result) const;
+  MOZ_MUST_USE bool ReadIntPtr(PickleIterator* iter, intptr_t* result) const;
+  MOZ_MUST_USE bool ReadUnsignedChar(PickleIterator* iter, unsigned char* result) const;
+  MOZ_MUST_USE bool ReadString(PickleIterator* iter, std::string* result) const;
+  MOZ_MUST_USE bool ReadWString(PickleIterator* iter, std::wstring* result) const;
+  MOZ_MUST_USE bool ReadData(PickleIterator* iter, const char** data, int* length) const;
+  MOZ_MUST_USE bool ReadBytes(PickleIterator* iter, const char** data, int length,
                               uint32_t alignment = sizeof(memberAlignmentType)) const;
 
   // Safer version of ReadInt() checks for the result not being negative.
   // Use it for reading the object sizes.
-  MOZ_MUST_USE bool ReadLength(void** iter, int* result) const;
+  MOZ_MUST_USE bool ReadLength(PickleIterator* iter, int* result) const;
+
+  void EndRead(PickleIterator& iter) const {
+    DCHECK(iter.iter_ == end_of_payload());
+  }
 
   // Methods for adding to the payload of the Pickle.  These values are
   // appended to the end of the Pickle's payload.  When reading values from a
   // Pickle, it is important to read them in the order in which they were added
   // to the Pickle.
   bool WriteBool(bool value) {
     return WriteInt(value ? 1 : 0);
   }
@@ -171,19 +190,16 @@ class Pickle {
   // Pickle. This saves a copy in cases where the data is not already
   // available in a buffer. The caller should take care to not write more
   // than the length it declares it will. Use ReadData to get the data.
   // Returns NULL on failure.
   //
   // The returned pointer will only be valid until the next write operation
   // on this Pickle.
   char* BeginWriteData(int length);
-  void EndRead(void* iter) const {
-    DCHECK(iter == end_of_payload());
-  }
 
   // Payload follows after allocation of Header (header size is customizable).
   struct Header {
     uint32_t payload_size;  // Specifies the size of the payload.
   };
 
   // Returns the header, cast to a user-specified type T.  The type T must be a
   // subclass of Header and its size must correspond to the header_size passed
@@ -197,22 +213,22 @@ class Pickle {
   const T* headerT() const {
     DCHECK(sizeof(T) == header_size_);
     return static_cast<const T*>(header_);
   }
 
   // Returns true if the given iterator could point to data with the given
   // length. If there is no room for the given data before the end of the
   // payload, returns false.
-  bool IteratorHasRoomFor(const void* iter, int len) const {
-    if ((len < 0) || (iter < header_) || iter > end_of_payload())
+  bool IteratorHasRoomFor(const PickleIterator& iter, int len) const {
+    if ((len < 0) || (iter.iter_ < header_) || iter.iter_ > end_of_payload())
       return false;
-    const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
+    const char* end_of_region = reinterpret_cast<const char*>(iter.iter_) + len;
     // Watch out for overflow in pointer calculation, which wraps.
-    return (iter <= end_of_region) && (end_of_region <= end_of_payload());
+    return (iter.iter_ <= end_of_region) && (end_of_region <= end_of_payload());
   }
 
   typedef uint32_t memberAlignmentType;
 
  protected:
   uint32_t payload_size() const { return header_->payload_size; }
 
   char* payload() {
@@ -262,18 +278,18 @@ class Pickle {
 
   static uint32_t AlignInt(int bytes) {
     return ConstantAligner<sizeof(memberAlignmentType)>::align(bytes);
   }
 
   // Moves the iterator by the given number of bytes, making sure it is aligned.
   // Pointer (iterator) is NOT aligned, but the change in the pointer
   // is guaranteed to be a multiple of sizeof(memberAlignmentType).
-  static void UpdateIter(void** iter, int bytes) {
-    *iter = static_cast<char*>(*iter) + AlignInt(bytes);
+  static void UpdateIter(PickleIterator* iter, int bytes) {
+    iter->iter_ = static_cast<char*>(iter->iter_) + AlignInt(bytes);
   }
 
   // Find the end of the pickled data that starts at range_start.  Returns NULL
   // if the entire Pickle is not found in the given data range.
   static const char* FindNext(uint32_t header_size,
                               const char* range_start,
                               const char* range_end);
 
@@ -282,15 +298,17 @@ class Pickle {
   static uint32_t GetLength(uint32_t header_size,
                             const char* range_start,
                             const char* range_end);
 
   // The allocation granularity of the payload.
   static const int kPayloadUnit;
 
  private:
+  friend class PickleIterator;
+
   Header* header_;
   uint32_t header_size_;
   uint32_t capacity_;
   uint32_t variable_buffer_offset_;
 };
 
 #endif  // BASE_PICKLE_H__
--- a/ipc/chromium/src/chrome/common/ipc_message.cc
+++ b/ipc/chromium/src/chrome/common/ipc_message.cc
@@ -121,17 +121,17 @@ bool Message::WriteFileDescriptor(const 
   WriteInt(file_descriptor_set()->size());
   if (descriptor.auto_close) {
     return file_descriptor_set()->AddAndAutoClose(descriptor.fd);
   } else {
     return file_descriptor_set()->Add(descriptor.fd);
   }
 }
 
-bool Message::ReadFileDescriptor(void** iter,
+bool Message::ReadFileDescriptor(PickleIterator* iter,
                                 base::FileDescriptor* descriptor) const {
   int descriptor_index;
   if (!ReadInt(iter, &descriptor_index))
     return false;
 
   FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get();
   if (!file_descriptor_set)
     return false;
--- a/ipc/chromium/src/chrome/common/ipc_message.h
+++ b/ipc/chromium/src/chrome/common/ipc_message.h
@@ -255,17 +255,17 @@ class Message : public Pickle {
 #if defined(OS_POSIX)
   // On POSIX, a message supports reading / writing FileDescriptor objects.
   // This is used to pass a file descriptor to the peer of an IPC channel.
 
   // Add a descriptor to the end of the set. Returns false iff the set is full.
   bool WriteFileDescriptor(const base::FileDescriptor& descriptor);
   // Get a file descriptor from the message. Returns false on error.
   //   iter: a Pickle iterator to the current location in the message.
-  bool ReadFileDescriptor(void** iter, base::FileDescriptor* descriptor) const;
+  bool ReadFileDescriptor(PickleIterator* iter, base::FileDescriptor* descriptor) const;
 
 #if defined(OS_MACOSX)
   void set_fd_cookie(uint32_t cookie) {
     header()->cookie = cookie;
   }
   uint32_t fd_cookie() const {
     return header()->cookie;
   }
--- a/ipc/chromium/src/chrome/common/ipc_message_utils.h
+++ b/ipc/chromium/src/chrome/common/ipc_message_utils.h
@@ -24,17 +24,17 @@
 
 namespace IPC {
 
 //-----------------------------------------------------------------------------
 // An iterator class for reading the fields contained within a Message.
 
 class MessageIterator {
  public:
-  explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
+  explicit MessageIterator(const Message& m) : msg_(m), iter_(m) {
   }
   int NextInt() const {
     int val;
     if (!msg_.ReadInt(&iter_, &val))
       NOTREACHED();
     return val;
   }
   intptr_t NextIntPtr() const {
@@ -57,17 +57,17 @@ class MessageIterator {
   }
   void NextData(const char** data, int* length) const {
     if (!msg_.ReadData(&iter_, data, length)) {
       NOTREACHED();
     }
   }
  private:
   const Message& msg_;
-  mutable void* iter_;
+  mutable PickleIterator iter_;
 };
 
 //-----------------------------------------------------------------------------
 // ParamTraits specializations, etc.
 //
 // The full set of types ParamTraits is specialized upon contains *possibly*
 // repeated types: unsigned long may be uint32_t or size_t, unsigned long long
 // may be uint64_t or size_t, nsresult may be uint32_t, and so on.  You can't
@@ -112,17 +112,17 @@ class MessageIterator {
 template <class P> struct ParamTraits;
 
 template <class P>
 static inline void WriteParam(Message* m, const P& p) {
   ParamTraits<P>::Write(m, p);
 }
 
 template <class P>
-static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
+static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, PickleIterator* iter,
                                                 P* p) {
   return ParamTraits<P>::Read(m, iter, p);
 }
 
 template <class P>
 static inline void LogParam(const P& p, std::wstring* l) {
   ParamTraits<P>::Log(p, l);
 }
@@ -133,73 +133,73 @@ template <class P>
 struct ParamTraitsFundamental {};
 
 template <>
 struct ParamTraitsFundamental<bool> {
   typedef bool param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteBool(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadBool(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(p ? L"true" : L"false");
   }
 };
 
 template <>
 struct ParamTraitsFundamental<int> {
   typedef int param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteInt(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadInt(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%d", p));
   }
 };
 
 template <>
 struct ParamTraitsFundamental<long> {
   typedef long param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteLong(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadLong(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%l", p));
   }
 };
 
 template <>
 struct ParamTraitsFundamental<unsigned long> {
   typedef unsigned long param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteULong(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadULong(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%ul", p));
   }
 };
 
 template <>
 struct ParamTraitsFundamental<long long> {
   typedef long long param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
  }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     const char *data;
     int data_size = 0;
     bool result = m->ReadData(iter, &data, &data_size);
     if (result && data_size == sizeof(param_type)) {
       memcpy(r, data, sizeof(param_type));
     } else {
       result = false;
       NOTREACHED();
@@ -212,17 +212,17 @@ struct ParamTraitsFundamental<long long>
 };
 
 template <>
 struct ParamTraitsFundamental<unsigned long long> {
   typedef unsigned long long param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
  }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     const char *data;
     int data_size = 0;
     bool result = m->ReadData(iter, &data, &data_size);
     if (result && data_size == sizeof(param_type)) {
       memcpy(r, data, sizeof(param_type));
     } else {
       result = false;
       NOTREACHED();
@@ -235,17 +235,17 @@ struct ParamTraitsFundamental<unsigned l
 };
 
 template <>
 struct ParamTraitsFundamental<double> {
   typedef double param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     const char *data;
     int data_size = 0;
     bool result = m->ReadData(iter, &data, &data_size);
     if (result && data_size == sizeof(param_type)) {
       memcpy(r, data, sizeof(param_type));
     } else {
       result = false;
       NOTREACHED();
@@ -264,73 +264,73 @@ template <class P>
 struct ParamTraitsFixed : ParamTraitsFundamental<P> {};
 
 template <>
 struct ParamTraitsFixed<int16_t> {
   typedef int16_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteInt16(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadInt16(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%hd", p));
   }
 };
 
 template <>
 struct ParamTraitsFixed<uint16_t> {
   typedef uint16_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteUInt16(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadUInt16(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%hu", p));
   }
 };
 
 template <>
 struct ParamTraitsFixed<uint32_t> {
   typedef uint32_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteUInt32(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadUInt32(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%u", p));
   }
 };
 
 template <>
 struct ParamTraitsFixed<int64_t> {
   typedef int64_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteInt64(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadInt64(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%" PRId64L, p));
   }
 };
 
 template <>
 struct ParamTraitsFixed<uint64_t> {
   typedef uint64_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteInt64(static_cast<int64_t>(p));
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadInt64(iter, reinterpret_cast<int64_t*>(r));
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%" PRIu64L, p));
   }
 };
 
 // Other standard C types.
@@ -339,17 +339,17 @@ template <class P>
 struct ParamTraitsLibC : ParamTraitsFixed<P> {};
 
 template <>
 struct ParamTraitsLibC<size_t> {
   typedef size_t param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteSize(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadSize(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%u", p));
   }
 };
 
 // std::* types.
@@ -358,31 +358,31 @@ template <class P>
 struct ParamTraitsStd : ParamTraitsLibC<P> {};
 
 template <>
 struct ParamTraitsStd<std::string> {
   typedef std::string param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteString(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadString(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(UTF8ToWide(p));
   }
 };
 
 template <>
 struct ParamTraitsStd<std::wstring> {
   typedef std::wstring param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteWString(p);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadWString(iter, r);
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(p);
   }
 };
 
 template <class K, class V>
@@ -391,17 +391,17 @@ struct ParamTraitsStd<std::map<K, V> > {
   static void Write(Message* m, const param_type& p) {
     WriteParam(m, static_cast<int>(p.size()));
     typename param_type::const_iterator iter;
     for (iter = p.begin(); iter != p.end(); ++iter) {
       WriteParam(m, iter->first);
       WriteParam(m, iter->second);
     }
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     int size;
     if (!ReadParam(m, iter, &size) || size < 0)
       return false;
     for (int i = 0; i < size; ++i) {
       K k;
       if (!ReadParam(m, iter, &k))
         return false;
       V& value = (*r)[k];
@@ -422,32 +422,32 @@ struct ParamTraitsWindows : ParamTraitsS
 
 #if defined(OS_WIN)
 template <>
 struct ParamTraitsWindows<HANDLE> {
   typedef HANDLE param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"0x%X", p));
   }
 };
 
 template <>
 struct ParamTraitsWindows<HWND> {
   typedef HWND param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"0x%X", p));
   }
 };
 #endif  // defined(OS_WIN)
@@ -481,17 +481,17 @@ struct ParamTraitsIPC<base::FileDescript
     WriteParam(m, valid);
 
     if (valid) {
       if (!m->WriteFileDescriptor(p)) {
         NOTREACHED() << "Too many file descriptors for one message!";
       }
     }
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     bool valid;
     if (!ReadParam(m, iter, &valid))
       return false;
 
     if (!valid) {
       r->fd = -1;
       r->auto_close = false;
       return true;
@@ -512,17 +512,17 @@ struct ParamTraitsIPC<base::FileDescript
 #if defined(OS_WIN)
 template<>
 struct ParamTraitsIPC<TransportDIB::Id> {
   typedef TransportDIB::Id param_type;
   static void Write(Message* m, const param_type& p) {
     WriteParam(m, p.handle);
     WriteParam(m, p.sequence_num);
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return (ReadParam(m, iter, &r->handle) &&
             ReadParam(m, iter, &r->sequence_num));
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(L"TransportDIB(");
     LogParam(p.handle, l);
     l->append(L", ");
     LogParam(p.sequence_num, l);
@@ -537,17 +537,17 @@ template <class P>
 struct ParamTraitsMozilla : ParamTraitsIPC<P> {};
 
 template <>
 struct ParamTraitsMozilla<nsresult> {
   typedef nsresult param_type;
   static void Write(Message* m, const param_type& p) {
     m->WriteUInt32(static_cast<uint32_t>(p));
   }
-  static bool Read(const Message* m, void** iter, param_type* r) {
+  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
     return m->ReadUInt32(iter, reinterpret_cast<uint32_t*>(r));
   }
   static void Log(const param_type& p, std::wstring* l) {
     l->append(StringPrintf(L"%u", static_cast<uint32_t>(p)));
   }
 };
 
 // Finally, ParamTraits itself.
--- a/ipc/glue/BackgroundUtils.h
+++ b/ipc/glue/BackgroundUtils.h
@@ -24,17 +24,17 @@ struct OriginAttributesParamTraits
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     nsAutoCString suffix;
     aParam.CreateSuffix(suffix);
     WriteParam(aMsg, suffix);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsAutoCString suffix;
     return ReadParam(aMsg, aIter, &suffix) &&
            aResult->PopulateFromSuffix(suffix);
   }
 };
 } // namespace detail
 
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -109,17 +109,17 @@ struct EnumSerializer {
   typedef typename mozilla::UnsignedStdintTypeForSize<sizeof(paramType)>::Type
           uintParamType;
 
   static void Write(Message* aMsg, const paramType& aValue) {
     MOZ_ASSERT(EnumValidator::IsLegalValue(aValue));
     WriteParam(aMsg, uintParamType(aValue));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
     uintParamType value;
     if (!ReadParam(aMsg, aIter, &value)) {
 #ifdef MOZ_CRASHREPORTER
       CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"),
                                          NS_LITERAL_CSTRING("Bad iter"));
 #endif
       return false;
     } else if (!EnumValidator::IsLegalValue(paramType(value))) {
@@ -225,17 +225,17 @@ struct ParamTraits<int8_t>
 {
   typedef int8_t paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aMsg->WriteBytes(&aParam, sizeof(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     const char* outp;
     if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
       return false;
 
     *aResult = *reinterpret_cast<const paramType*>(outp);
     return true;
   }
@@ -246,17 +246,17 @@ struct ParamTraits<uint8_t>
 {
   typedef uint8_t paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aMsg->WriteBytes(&aParam, sizeof(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     const char* outp;
     if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
       return false;
 
     *aResult = *reinterpret_cast<const paramType*>(outp);
     return true;
   }
@@ -266,17 +266,17 @@ struct ParamTraits<uint8_t>
 // See above re: keeping definitions in sync
 template<>
 struct ParamTraits<base::FileDescriptor>
 {
   typedef base::FileDescriptor paramType;
   static void Write(Message* aMsg, const paramType& aParam) {
     NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
     NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
     return false;
   }
 };
 #endif  // !defined(OS_POSIX)
 
 template <>
 struct ParamTraits<nsACString>
@@ -292,17 +292,17 @@ struct ParamTraits<nsACString>
       // represents a nullptr pointer
       return;
 
     uint32_t length = aParam.Length();
     WriteParam(aMsg, length);
     aMsg->WriteBytes(aParam.BeginReading(), length);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool isVoid;
     if (!aMsg->ReadBool(aIter, &isVoid))
       return false;
 
     if (isVoid) {
       aResult->SetIsVoid(true);
       return true;
@@ -342,17 +342,17 @@ struct ParamTraits<nsAString>
       // represents a nullptr pointer
       return;
 
     uint32_t length = aParam.Length();
     WriteParam(aMsg, length);
     aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(char16_t));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool isVoid;
     if (!aMsg->ReadBool(aIter, &isVoid))
       return false;
 
     if (isVoid) {
       aResult->SetIsVoid(true);
       return true;
@@ -456,17 +456,17 @@ struct ParamTraits<nsTArray<E>>
       for (uint32_t index = 0; index < length; index++) {
         WriteParam(aMsg, aParam[index]);
       }
     }
   }
 
   // This method uses infallible allocation so that an OOM failure will
   // show up as an OOM crash rather than an IPC FatalError.
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint32_t length;
     if (!ReadParam(aMsg, aIter, &length)) {
       return false;
     }
 
     if (sUseWriteBytes) {
       int pickledLength = 0;
@@ -513,17 +513,17 @@ struct ParamTraits<FallibleTArray<E>>
   typedef FallibleTArray<E> paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<const nsTArray<E>&>(aParam));
   }
 
   // Deserialize the array infallibly, but return a FallibleTArray.
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsTArray<E> temp;
     if (!ReadParam(aMsg, aIter, &temp))
       return false;
 
     aResult->SwapElements(temp);
     return true;
   }
@@ -545,17 +545,17 @@ struct ParamTraits<float>
 {
   typedef float paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aMsg->WriteBytes(&aParam, sizeof(paramType));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     const char* outFloat;
     if (!aMsg->ReadBytes(aIter, &outFloat, sizeof(float)))
       return false;
     *aResult = *reinterpret_cast<const float*>(outFloat);
     return true;
   }
 
@@ -573,30 +573,30 @@ struct ParamTraits<nsCSSProperty>
 {};
 
 template<>
 struct ParamTraits<mozilla::void_t>
 {
   typedef mozilla::void_t paramType;
   static void Write(Message* aMsg, const paramType& aParam) { }
   static bool
-  Read(const Message* aMsg, void** aIter, paramType* aResult)
+  Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     *aResult = paramType();
     return true;
   }
 };
 
 template<>
 struct ParamTraits<mozilla::null_t>
 {
   typedef mozilla::null_t paramType;
   static void Write(Message* aMsg, const paramType& aParam) { }
   static bool
-  Read(const Message* aMsg, void** aIter, paramType* aResult)
+  Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     *aResult = paramType();
     return true;
   }
 };
 
 template<>
 struct ParamTraits<nsID>
@@ -608,17 +608,17 @@ struct ParamTraits<nsID>
     WriteParam(aMsg, aParam.m0);
     WriteParam(aMsg, aParam.m1);
     WriteParam(aMsg, aParam.m2);
     for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) {
       WriteParam(aMsg, aParam.m3[i]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if(!ReadParam(aMsg, aIter, &(aResult->m0)) ||
        !ReadParam(aMsg, aIter, &(aResult->m1)) ||
        !ReadParam(aMsg, aIter, &(aResult->m2)))
       return false;
 
     for (unsigned int i = 0; i < mozilla::ArrayLength(aResult->m3); i++)
       if (!ReadParam(aMsg, aIter, &(aResult->m3[i])))
@@ -643,31 +643,31 @@ struct ParamTraits<nsID>
 template<>
 struct ParamTraits<mozilla::TimeDuration>
 {
   typedef mozilla::TimeDuration paramType;
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mValue);
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mValue);
   };
 };
 
 template<>
 struct ParamTraits<mozilla::TimeStamp>
 {
   typedef mozilla::TimeStamp paramType;
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mValue);
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mValue);
   };
 };
 
 #ifdef XP_WIN
 
 template<>
@@ -676,17 +676,17 @@ struct ParamTraits<mozilla::TimeStampVal
   typedef mozilla::TimeStampValue paramType;
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mGTC);
     WriteParam(aMsg, aParam.mQPC);
     WriteParam(aMsg, aParam.mHasQPC);
     WriteParam(aMsg, aParam.mIsNull);
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mGTC) &&
             ReadParam(aMsg, aIter, &aResult->mQPC) &&
             ReadParam(aMsg, aIter, &aResult->mHasQPC) &&
             ReadParam(aMsg, aIter, &aResult->mIsNull));
   }
 };
 
@@ -697,17 +697,17 @@ struct ParamTraits<mozilla::dom::ipc::St
 {
   typedef mozilla::dom::ipc::StructuredCloneData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aParam.WriteIPCParams(aMsg);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return aResult->ReadIPCParams(aMsg, aIter);
   }
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
     LogParam(aParam.DataLength(), aLog);
   }
@@ -718,17 +718,17 @@ struct ParamTraits<mozilla::net::WebSock
 {
   typedef mozilla::net::WebSocketFrameData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aParam.WriteIPCParams(aMsg);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return aResult->ReadIPCParams(aMsg, aIter);
   }
 };
 
 template <>
 struct ParamTraits<mozilla::SerializedStructuredCloneBuffer>
 {
@@ -738,17 +738,17 @@ struct ParamTraits<mozilla::SerializedSt
   {
     WriteParam(aMsg, aParam.dataLength);
     if (aParam.dataLength) {
       // Structured clone data must be 64-bit aligned.
       aMsg->WriteBytes(aParam.data, aParam.dataLength, sizeof(uint64_t));
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->dataLength)) {
       return false;
     }
 
     if (aResult->dataLength) {
       const char** buffer =
         const_cast<const char**>(reinterpret_cast<char**>(&aResult->data));
@@ -787,17 +787,17 @@ struct ParamTraits<mozilla::Maybe<T>>
     if (param.isSome()) {
       WriteParam(msg, true);
       WriteParam(msg, param.value());
     } else {
       WriteParam(msg, false);
     }
   }
 
-  static bool Read(const Message* msg, void** iter, paramType* result)
+  static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
   {
     bool isSome;
     if (!ReadParam(msg, iter, &isSome)) {
       return false;
     }
     if (isSome) {
       T tmp;
       if (!ReadParam(msg, iter, &tmp)) {
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -185,17 +185,17 @@ public:
     IPC::WriteParam(this, static_cast<uint32_t>(aProtocol));
   }
 
   static bool Read(const IPC::Message& aMsg,
                    TransportDescriptor* aDescriptor,
                    ProcessId* aOtherProcess,
                    ProtocolId* aProtocol)
   {
-    void* iter = nullptr;
+    PickleIterator iter(aMsg);
     if (!IPC::ReadParam(&aMsg, &iter, aDescriptor) ||
         !IPC::ReadParam(&aMsg, &iter, aOtherProcess) ||
         !IPC::ReadParam(&aMsg, &iter, reinterpret_cast<uint32_t*>(aProtocol))) {
       return false;
     }
     aMsg.EndRead(iter);
     return true;
   }
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -181,17 +181,17 @@ public:
     // XXX odd ducks, acknowledged
     virtual ProcessId OtherPid() const = 0;
     virtual MessageChannel* GetIPCChannel() = 0;
 
     // The implementation of function is generated by code generator.
     virtual void CloneManagees(ListenerT* aSource,
                                ProtocolCloneContext* aCtx) = 0;
 
-    Maybe<ListenerT*> ReadActor(const IPC::Message* aMessage, void** aIter, bool aNullable,
+    Maybe<ListenerT*> ReadActor(const IPC::Message* aMessage, PickleIterator* aIter, bool aNullable,
                                 const char* aActorDescription, int32_t aProtocolTypeId);
 };
 
 typedef IPCMessageStart ProtocolId;
 
 /**
  * All RPC protocols should implement this interface.
  */
@@ -359,17 +359,17 @@ Open(const PrivateIPDLInterface&,
 
 bool
 UnpackChannelOpened(const PrivateIPDLInterface&,
                     const IPC::Message&,
                     TransportDescriptor*, base::ProcessId*, ProtocolId*);
 
 template<typename ListenerT>
 Maybe<ListenerT*>
-IProtocolManager<ListenerT>::ReadActor(const IPC::Message* aMessage, void** aIter, bool aNullable,
+IProtocolManager<ListenerT>::ReadActor(const IPC::Message* aMessage, PickleIterator* aIter, bool aNullable,
                                        const char* aActorDescription, int32_t aProtocolTypeId)
 {
     int32_t id;
     if (!IPC::ReadParam(aMessage, aIter, &id)) {
         ActorIdReadError(aActorDescription);
         return Nothing();
     }
 
@@ -609,17 +609,17 @@ struct ParamTraits<mozilla::ipc::ActorHa
 {
     typedef mozilla::ipc::ActorHandle paramType;
 
     static void Write(Message* aMsg, const paramType& aParam)
     {
         IPC::WriteParam(aMsg, aParam.mId);
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         int id;
         if (IPC::ReadParam(aMsg, aIter, &id)) {
             aResult->mId = id;
             return true;
         }
         return false;
     }
@@ -648,17 +648,17 @@ struct ParamTraits<mozilla::ipc::Endpoin
         mozilla::ipc::TransportDescriptor desc = mozilla::ipc::DuplicateDescriptor(aParam.mTransport);
         IPC::WriteParam(aMsg, desc);
 
         IPC::WriteParam(aMsg, aParam.mMyPid);
         IPC::WriteParam(aMsg, aParam.mOtherPid);
         IPC::WriteParam(aMsg, static_cast<uint32_t>(aParam.mProtocolId));
     }
 
-    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
     {
         MOZ_RELEASE_ASSERT(!aResult->mValid);
         aResult->mValid = true;
         uint32_t mode, protocolId;
         if (!IPC::ReadParam(aMsg, aIter, &mode) ||
             !IPC::ReadParam(aMsg, aIter, &aResult->mTransport) ||
             !IPC::ReadParam(aMsg, aIter, &aResult->mMyPid) ||
             !IPC::ReadParam(aMsg, aIter, &aResult->mOtherPid) ||
--- a/ipc/glue/SharedMemory.h
+++ b/ipc/glue/SharedMemory.h
@@ -57,17 +57,17 @@ public:
   virtual bool Create(size_t size) = 0;
   virtual bool Map(size_t nBytes) = 0;
 
   virtual void CloseHandle() = 0;
 
   virtual SharedMemoryType Type() const = 0;
 
   virtual bool ShareHandle(base::ProcessId aProcessId, IPC::Message* aMessage) = 0;
-  virtual bool ReadHandle(const IPC::Message* aMessage, void** aIter) = 0;
+  virtual bool ReadHandle(const IPC::Message* aMessage, PickleIterator* aIter) = 0;
 
   void
   Protect(char* aAddr, size_t aSize, int aRights)
   {
     char* memStart = reinterpret_cast<char*>(memory());
     if (!memStart)
       NS_RUNTIMEABORT("SharedMemory region points at NULL!");
     char* memEnd = memStart + Size();
@@ -132,17 +132,17 @@ public:
     Handle handle;
     if (!ShareToProcess(aProcessId, &handle)) {
       return false;
     }
     IPC::WriteParam(aMessage, handle);
     return true;
   }
 
-  virtual bool ReadHandle(const IPC::Message* aMessage, void** aIter) override
+  virtual bool ReadHandle(const IPC::Message* aMessage, PickleIterator* aIter) override
   {
     Handle handle;
     return IPC::ReadParam(aMessage, aIter, &handle) &&
            IsHandleValid(handle) &&
            SetHandle(handle);
   }
 };
 
--- a/ipc/glue/Shmem.cpp
+++ b/ipc/glue/Shmem.cpp
@@ -29,17 +29,17 @@ public:
     IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL)
   {
     IPC::WriteParam(this, aIPDLId);
     IPC::WriteParam(this, aSize);
     IPC::WriteParam(this, int32_t(aType));
   }
 
   static bool
-  ReadInfo(const Message* msg, void** iter,
+  ReadInfo(const Message* msg, PickleIterator* iter,
            id_t* aIPDLId,
            size_t* aSize,
            SharedMemory::SharedMemoryType* aType)
   {
     if (!IPC::ReadParam(msg, iter, aIPDLId) ||
         !IPC::ReadParam(msg, iter, aSize) ||
         !IPC::ReadParam(msg, iter, reinterpret_cast<int32_t*>(aType)))
       return false;
@@ -95,17 +95,17 @@ CreateSegment(SharedMemory::SharedMemory
 static already_AddRefed<SharedMemory>
 ReadSegment(const IPC::Message& aDescriptor, Shmem::id_t* aId, size_t* aNBytes, size_t aExtraSize)
 {
   if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type()) {
     NS_ERROR("expected 'shmem created' message");
     return nullptr;
   }
   SharedMemory::SharedMemoryType type;
-  void* iter = nullptr;
+  PickleIterator iter(aDescriptor);
   if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, aNBytes, &type)) {
     return nullptr;
   }
   RefPtr<SharedMemory> segment = NewSegment(type);
   if (!segment) {
     return nullptr;
   }
   if (!segment->ReadHandle(&aDescriptor, &iter)) {
--- a/ipc/glue/Shmem.h
+++ b/ipc/glue/Shmem.h
@@ -279,17 +279,17 @@ struct ParamTraits<mozilla::ipc::Shmem>
   // member, but IPDL internally uses mId to properly initialize a
   // "real" Shmem
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mId);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     paramType::id_t id;
     if (!ReadParam(aMsg, aIter, &id))
       return false;
     aResult->mId = id;
     return true;
   }
 
--- a/ipc/glue/Transport_posix.h
+++ b/ipc/glue/Transport_posix.h
@@ -28,17 +28,17 @@ namespace IPC {
 template<>
 struct ParamTraits<mozilla::ipc::TransportDescriptor>
 {
   typedef mozilla::ipc::TransportDescriptor paramType;
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mFd);
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mFd);
   }
 };
 
 } // namespace IPC
 
 
--- a/ipc/glue/Transport_win.h
+++ b/ipc/glue/Transport_win.h
@@ -54,17 +54,17 @@ struct ParamTraits<mozilla::ipc::Transpo
       }
     }
 
     WriteParam(aMsg, aParam.mPipeName);
     WriteParam(aMsg, pipe);
     WriteParam(aMsg, duplicateFromProcessId);
     WriteParam(aMsg, aParam.mDestinationProcessId);
   }
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     DWORD duplicateFromProcessId;
     bool r = (ReadParam(aMsg, aIter, &aResult->mPipeName) &&
               ReadParam(aMsg, aIter, &aResult->mServerPipeHandle) &&
               ReadParam(aMsg, aIter, &duplicateFromProcessId) &&
               ReadParam(aMsg, aIter, &aResult->mDestinationProcessId));
     if (!r) {
       return r;
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -128,16 +128,19 @@ def _actorManager(actor):
     return ExprSelect(actor, '->', 'mManager')
 
 def _actorState(actor):
     return ExprSelect(actor, '->', 'mState')
 
 def _backstagePass():
     return ExprCall(ExprVar('mozilla::ipc::PrivateIPDLInterface'))
 
+def _iterType(ptr):
+    return Type('PickleIterator', ptr=ptr)
+
 def _nullState(proto=None):
     pfx = ''
     if proto is not None:  pfx = proto.name() +'::'
     return ExprVar(pfx +'__Null')
 
 def _errorState(proto=None):
     pfx = ''
     if proto is not None:  pfx = proto.name() +'::'
@@ -4117,17 +4120,18 @@ class _GenerateProtocolActorCode(ipdl.as
 
         case = StmtBlock()
 
         rawvar = ExprVar('rawmem')
         idvar = ExprVar('id')
         itervar = ExprVar('iter')
         case.addstmts([
             StmtDecl(Decl(_shmemIdType(), idvar.name)),
-            StmtDecl(Decl(Type.VOIDPTR, itervar.name), init=ExprLiteral.NULL)
+            StmtDecl(Decl(_iterType(ptr=0), itervar.name), init=ExprCall(ExprVar('PickleIterator'),
+                                                                         args=[ self.msgvar ]))
         ])
 
         failif = StmtIf(ExprNot(
             ExprCall(ExprVar('IPC::ReadParam'),
                      args=[ ExprAddrOf(self.msgvar), ExprAddrOf(itervar),
                             ExprAddrOf(idvar) ])))
         failif.addifstmt(StmtReturn(_Result.PayloadError))
 
@@ -4664,17 +4668,17 @@ class _GenerateProtocolActorCode(ipdl.as
             T=template)
 
     def readMethodDecl(self, outtype, var, template=None):
         return MethodDecl(
             'Read',
             params=[ Decl(outtype, var.name),
                      Decl(Type('Message', ptr=1, const=1),
                           self.msgvar.name),
-                     Decl(Type('void', ptrptr=1), self.itervar.name)],
+                     Decl(_iterType(ptr=1), self.itervar.name)],
             warn_unused=not template,
             T=template,
             ret=Type.BOOL)
 
     def maybeAddNullabilityArg(self, ipdltype, call):
         if ipdltype and ipdltype.isIPDL() and ipdltype.isActor():
             if ipdltype.nullable:
                 call.args.append(ExprLiteral.TRUE)
@@ -5145,18 +5149,19 @@ class _GenerateProtocolActorCode(ipdl.as
             handletype = Type('ActorHandle')
             decls = [ StmtDecl(Decl(handletype, handlevar.name)) ]
             reads = [ self.checkedRead(None, ExprAddrOf(handlevar), msgexpr,
                                        ExprAddrOf(self.itervar),
                                        errfn, "'%s'" % handletype.name) ]
             start = 1
 
         stmts.extend((
-            [ StmtDecl(Decl(Type.VOIDPTR, self.itervar.name),
-                     init=ExprLiteral.NULL) ]
+            [ StmtDecl(Decl(_iterType(ptr=0), self.itervar.name),
+                     init=ExprCall(ExprVar('PickleIterator'),
+                                   args=[ msgvar ])) ]
             + decls + [ StmtDecl(Decl(p.bareType(side), p.var().name))
                       for p in md.params ]
             + [ Whitespace.NL ]
             + reads + [ self.checkedRead(p.ipdltype, ExprAddrOf(p.var()),
                                          msgexpr, ExprAddrOf(itervar),
                                          errfn, "'%s'" % p.bareType(side).name)
                         for p in md.params[start:] ]
             + [ self.endRead(msgvar, itervar) ]))
@@ -5169,18 +5174,19 @@ class _GenerateProtocolActorCode(ipdl.as
                    self.logMessage(md, replyexpr,
                                    'Received reply ', actor, receiving=True) ]
         if 0 == len(md.returns):
             return stmts
 
         itervar = self.itervar
         stmts.extend(
             [ Whitespace.NL,
-              StmtDecl(Decl(Type.VOIDPTR, itervar.name),
-                       init=ExprLiteral.NULL) ]
+              StmtDecl(Decl(_iterType(ptr=0), itervar.name),
+                       init=ExprCall(ExprVar('PickleIterator'),
+                                     args=[ self.replyvar ])) ]
             + [ self.checkedRead(r.ipdltype, r.var(),
                                  ExprAddrOf(self.replyvar),
                                  ExprAddrOf(self.itervar),
                                  errfn, "'%s'" % r.bareType(side).name)
                 for r in md.returns ]
             + [ self.endRead(self.replyvar, itervar) ])
 
         return stmts
--- a/ipc/ipdl/test/cxx/IPDLUnitTestUtils.h
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestUtils.h
@@ -14,14 +14,14 @@ namespace IPC {
 
 template<>
 struct ParamTraits<mozilla::_ipdltest::Bad>
 {
   typedef mozilla::_ipdltest::Bad paramType;
 
   // Defined in TestActorPunning.cpp.
   static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
 };
 
 } // namespace IPC
 
 #endif // mozilla__ipdltest_IPDLUnitTestUtils
--- a/ipc/ipdl/test/cxx/TestActorPunning.cpp
+++ b/ipc/ipdl/test/cxx/TestActorPunning.cpp
@@ -115,17 +115,17 @@ ParamTraits<Bad>::Write(Message* aMsg, c
     ptr -= intptr_t(sizeof(ActorHandle));
     ActorHandle* ah = reinterpret_cast<ActorHandle*>(ptr);
     if (ah->mId != -3)
         fail("guessed wrong offset (value is %d, should be -3)", ah->mId);
     ah->mId = -2;
 }
 
 /*static*/ bool
-ParamTraits<Bad>::Read(const Message* aMsg, void** aIter, paramType* aResult)
+ParamTraits<Bad>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
 {
     const char* ptr;
     int len;
     mozilla::Unused << aMsg->ReadData(aIter, &ptr, &len);
     return true;
 }
 
 } // namespace IPC
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -9287,17 +9287,17 @@ static void UpdateDisplayPortMarginsForP
 
 /* static */ void
 nsLayoutUtils::UpdateDisplayPortMarginsFromPendingMessages() {
   if (mozilla::dom::ContentChild::GetSingleton() &&
       mozilla::dom::ContentChild::GetSingleton()->GetIPCChannel()) {
     mozilla::dom::ContentChild::GetSingleton()->GetIPCChannel()->PeekMessages(
       [](const IPC::Message& aMsg) -> bool {
         if (aMsg.type() == mozilla::layers::PAPZ::Msg_UpdateFrame__ID) {
-          void* iter = nullptr;
+          PickleIterator iter(aMsg);
           FrameMetrics frame;
           if (!IPC::ReadParam(&aMsg, &iter, &frame)) {
             MOZ_ASSERT(false);
             return true;
           }
 
           UpdateDisplayPortMarginsForPendingMetrics(frame);
         }
--- a/layout/generic/VisibilityIPC.h
+++ b/layout/generic/VisibilityIPC.h
@@ -24,17 +24,17 @@ struct ParamTraits<mozilla::VisibilityCo
 {
   typedef mozilla::VisibilityCounter paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, uint8_t(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint8_t valueAsByte;
     if (ReadParam(aMsg, aIter, &valueAsByte)) {
       *aResult = paramType(valueAsByte);
       return true;
     }
     return false;
   }
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -49,17 +49,17 @@ struct ParamTraits<Permission>
   {
     WriteParam(aMsg, aParam.origin);
     WriteParam(aMsg, aParam.type);
     WriteParam(aMsg, aParam.capability);
     WriteParam(aMsg, aParam.expireType);
     WriteParam(aMsg, aParam.expireTime);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, Permission* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, Permission* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->origin) &&
            ReadParam(aMsg, aIter, &aResult->type) &&
            ReadParam(aMsg, aIter, &aResult->capability) &&
            ReadParam(aMsg, aIter, &aResult->expireType) &&
            ReadParam(aMsg, aIter, &aResult->expireTime);
   }
 
@@ -107,17 +107,17 @@ struct ParamTraits<mozilla::net::NetAddr
         nsPrintfCString msg("%d", aParam.raw.family);
         CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg);
       }
 #endif
       NS_RUNTIMEABORT("Unknown socket family");
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, mozilla::net::NetAddr* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, mozilla::net::NetAddr* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->raw.family))
       return false;
 
     if (aResult->raw.family == AF_UNSPEC) {
       const char *tmp;
       if (aMsg->ReadBytes(aIter, &tmp, sizeof(aResult->raw.data))) {
         memcpy(&(aResult->raw.data), tmp, sizeof(aResult->raw.data));
@@ -169,17 +169,17 @@ struct ParamTraits<mozilla::net::Resourc
     WriteParam(aMsg, aParam.transferSize);
     WriteParam(aMsg, aParam.encodedBodySize);
     WriteParam(aMsg, aParam.protocolVersion);
 
     WriteParam(aMsg, aParam.cacheReadStart);
     WriteParam(aMsg, aParam.cacheReadEnd);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, mozilla::net::ResourceTimingStruct* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, mozilla::net::ResourceTimingStruct* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->domainLookupStart) &&
            ReadParam(aMsg, aIter, &aResult->domainLookupEnd) &&
            ReadParam(aMsg, aIter, &aResult->connectStart) &&
            ReadParam(aMsg, aIter, &aResult->connectEnd) &&
            ReadParam(aMsg, aIter, &aResult->requestStart) &&
            ReadParam(aMsg, aIter, &aResult->responseStart) &&
            ReadParam(aMsg, aIter, &aResult->responseEnd) &&
--- a/netwerk/protocol/http/PHttpChannelParams.h
+++ b/netwerk/protocol/http/PHttpChannelParams.h
@@ -49,17 +49,17 @@ struct ParamTraits<mozilla::net::Request
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mHeader);
     WriteParam(aMsg, aParam.mValue);
     WriteParam(aMsg, aParam.mMerge);
     WriteParam(aMsg, aParam.mEmpty);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->mHeader) ||
         !ReadParam(aMsg, aIter, &aResult->mValue)  ||
         !ReadParam(aMsg, aIter, &aResult->mMerge)  ||
         !ReadParam(aMsg, aIter, &aResult->mEmpty))
       return false;
 
     return true;
@@ -74,17 +74,17 @@ struct ParamTraits<mozilla::net::nsHttpA
   static void Write(Message* aMsg, const paramType& aParam)
   {
     // aParam.get() cannot be null.
     MOZ_ASSERT(aParam.get(), "null nsHTTPAtom value");
     nsAutoCString value(aParam.get());
     WriteParam(aMsg, value);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsAutoCString value;
     if (!ReadParam(aMsg, aIter, &value))
       return false;
 
     *aResult = mozilla::net::nsHttp::ResolveAtom(value.get());
     MOZ_ASSERT(aResult->get(), "atom table not initialized");
     return true;
@@ -116,17 +116,17 @@ struct ParamTraits<mozilla::net::nsHttpH
       case mozilla::net::nsHttpHeaderArray::eVarietyResponseNetOriginal:
         WriteParam(aMsg, (uint8_t)4);
         break;
       case mozilla::net::nsHttpHeaderArray::eVarietyResponse:
         WriteParam(aMsg, (uint8_t)5);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint8_t variety;
     if (!ReadParam(aMsg, aIter, &aResult->header) ||
         !ReadParam(aMsg, aIter, &aResult->value)  ||
         !ReadParam(aMsg, aIter, &variety))
       return false;
 
     switch (variety) {
@@ -164,17 +164,17 @@ struct ParamTraits<mozilla::net::nsHttpH
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     paramType& p = const_cast<paramType&>(aParam);
 
     WriteParam(aMsg, p.mHeaders);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->mHeaders))
       return false;
 
     return true;
   }
 };
 
@@ -193,17 +193,17 @@ struct ParamTraits<mozilla::net::nsHttpR
     WriteParam(aMsg, aParam.mContentType);
     WriteParam(aMsg, aParam.mContentCharset);
     WriteParam(aMsg, aParam.mCacheControlPrivate);
     WriteParam(aMsg, aParam.mCacheControlNoStore);
     WriteParam(aMsg, aParam.mCacheControlNoCache);
     WriteParam(aMsg, aParam.mPragmaNoCache);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->mHeaders)             ||
         !ReadParam(aMsg, aIter, &aResult->mVersion)             ||
         !ReadParam(aMsg, aIter, &aResult->mStatus)              ||
         !ReadParam(aMsg, aIter, &aResult->mStatusText)          ||
         !ReadParam(aMsg, aIter, &aResult->mContentLength)       ||
         !ReadParam(aMsg, aIter, &aResult->mContentType)         ||
         !ReadParam(aMsg, aIter, &aResult->mContentCharset)      ||
--- a/netwerk/protocol/websocket/WebSocketFrame.cpp
+++ b/netwerk/protocol/websocket/WebSocketFrame.cpp
@@ -132,17 +132,17 @@ WebSocketFrameData::WriteIPCParams(IPC::
   WriteParam(aMessage, mOpCode);
   WriteParam(aMessage, mMaskBit);
   WriteParam(aMessage, mMask);
   WriteParam(aMessage, mPayload);
 }
 
 bool
 WebSocketFrameData::ReadIPCParams(const IPC::Message* aMessage,
-                                  void** aIter)
+                                  PickleIterator* aIter)
 {
   if (!ReadParam(aMessage, aIter, &mTimeStamp)) {
     return false;
   }
 
 #define ReadParamHelper(x)                     \
   {                                            \
     bool bit;                                  \
--- a/netwerk/protocol/websocket/WebSocketFrame.h
+++ b/netwerk/protocol/websocket/WebSocketFrame.h
@@ -29,17 +29,17 @@ public:
                      bool aRsvBit1, bool aRsvBit2, bool aRsvBit3,
                      uint8_t aOpCode, bool aMaskBit, uint32_t aMask,
                      const nsCString& aPayload);
 
   ~WebSocketFrameData();
 
   // For IPC serialization
   void WriteIPCParams(IPC::Message* aMessage) const;
-  bool ReadIPCParams(const IPC::Message* aMessage, void** aIter);
+  bool ReadIPCParams(const IPC::Message* aMessage, PickleIterator* aIter);
 
   DOMHighResTimeStamp mTimeStamp;
 
   bool mFinBit : 1;
   bool mRsvBit1 : 1;
   bool mRsvBit2 : 1;
   bool mRsvBit3 : 1;
   bool mMaskBit : 1;
--- a/toolkit/components/alerts/AlertNotificationIPCSerializer.h
+++ b/toolkit/components/alerts/AlertNotificationIPCSerializer.h
@@ -63,17 +63,17 @@ struct ParamTraits<AlertNotificationType
     WriteParam(aMsg, cookie);
     WriteParam(aMsg, dir);
     WriteParam(aMsg, lang);
     WriteParam(aMsg, data);
     WriteParam(aMsg, IPC::Principal(principal));
     WriteParam(aMsg, inPrivateBrowsing);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool isNull;
     NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &isNull), false);
     if (isNull) {
       *aResult = nullptr;
       return true;
     }
 
--- a/widget/WidgetMessageUtils.h
+++ b/widget/WidgetMessageUtils.h
@@ -16,24 +16,24 @@ struct ParamTraits<LookAndFeelInt>
   typedef LookAndFeelInt paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.id);
     WriteParam(aMsg, aParam.value);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     int32_t id, value;
     if (ReadParam(aMsg, aIter, &id) &&
         ReadParam(aMsg, aIter, &value)) {
       aResult->id = id;
       aResult->value = value;
       return true;
     }
     return false;
   }
 };
 
 } // namespace IPC
 
-#endif // WidgetMessageUtils_h
\ No newline at end of file
+#endif // WidgetMessageUtils_h
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -23,17 +23,17 @@ struct ParamTraits<mozilla::EventMessage
 {
   typedef mozilla::EventMessage paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<const mozilla::EventMessageType&>(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     mozilla::EventMessageType eventMessage = 0;
     bool ret = ReadParam(aMsg, aIter, &eventMessage);
     *aResult = static_cast<paramType>(eventMessage);
     return ret;
   }
 };
 
@@ -42,17 +42,17 @@ struct ParamTraits<mozilla::BaseEventFla
 {
   typedef mozilla::BaseEventFlags paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     aMsg->WriteBytes(&aParam, sizeof(aParam));
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     const char* outp;
     if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult))) {
       return false;
     }
     *aResult = *reinterpret_cast<const paramType*>(outp);
     return true;
   }
@@ -69,17 +69,17 @@ struct ParamTraits<mozilla::WidgetEvent>
       static_cast<mozilla::EventClassIDType>(aParam.mClass));
     WriteParam(aMsg, aParam.mMessage);
     WriteParam(aMsg, aParam.mRefPoint);
     WriteParam(aMsg, aParam.mTime);
     WriteParam(aMsg, aParam.mTimeStamp);
     WriteParam(aMsg, aParam.mFlags);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     mozilla::EventClassIDType eventClassID = 0;
     bool ret = ReadParam(aMsg, aIter, &eventClassID) &&
                ReadParam(aMsg, aIter, &aResult->mMessage) &&
                ReadParam(aMsg, aIter, &aResult->mRefPoint) &&
                ReadParam(aMsg, aIter, &aResult->mTime) &&
                ReadParam(aMsg, aIter, &aResult->mTimeStamp) &&
                ReadParam(aMsg, aIter, &aResult->mFlags);
@@ -93,34 +93,34 @@ struct ParamTraits<mozilla::NativeEventD
 {
   typedef mozilla::NativeEventData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mBuffer);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mBuffer);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::WidgetGUIEvent>
 {
   typedef mozilla::WidgetGUIEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetEvent>(aParam));
     WriteParam(aMsg, aParam.mPluginEvent);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, static_cast<mozilla::WidgetEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mPluginEvent);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::WidgetInputEvent>
@@ -128,17 +128,17 @@ struct ParamTraits<mozilla::WidgetInputE
   typedef mozilla::WidgetInputEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
     WriteParam(aMsg, aParam.mModifiers);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mModifiers);
   }
 };
 
 template<>
@@ -151,17 +151,17 @@ struct ParamTraits<mozilla::WidgetMouseE
     WriteParam(aMsg, static_cast<mozilla::WidgetInputEvent>(aParam));
     WriteParam(aMsg, aParam.button);
     WriteParam(aMsg, aParam.buttons);
     WriteParam(aMsg, aParam.pressure);
     WriteParam(aMsg, aParam.hitCluster);
     WriteParam(aMsg, aParam.inputSource);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetInputEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->button) &&
            ReadParam(aMsg, aIter, &aResult->buttons) &&
            ReadParam(aMsg, aIter, &aResult->pressure) &&
            ReadParam(aMsg, aIter, &aResult->hitCluster) &&
            ReadParam(aMsg, aIter, &aResult->inputSource);
@@ -189,17 +189,17 @@ struct ParamTraits<mozilla::WidgetWheelE
     WriteParam(aMsg, static_cast<uint8_t>(aParam.mScrollType));
     WriteParam(aMsg, aParam.mOverflowDeltaX);
     WriteParam(aMsg, aParam.mOverflowDeltaY);
     WriteParam(aMsg, aParam.mViewPortIsOverscrolled);
     WriteParam(aMsg, aParam.mCanTriggerSwipe);
     WriteParam(aMsg, aParam.mAllowToOverrideSystemScrollSpeed);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint8_t scrollType = 0;
     bool rv =
       ReadParam(aMsg, aIter,
                 static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
       ReadParam(aMsg, aIter, &aResult->mDeltaX) &&
       ReadParam(aMsg, aIter, &aResult->mDeltaY) &&
       ReadParam(aMsg, aIter, &aResult->mDeltaZ) &&
@@ -233,17 +233,17 @@ struct ParamTraits<mozilla::WidgetMouseE
     WriteParam(aMsg, aParam.mIgnoreRootScrollFrame);
     WriteParam(aMsg, static_cast<paramType::ReasonType>(aParam.mReason));
     WriteParam(aMsg, static_cast<paramType::ContextMenuTriggerType>(
                        aParam.mContextMenuTrigger));
     WriteParam(aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom));
     WriteParam(aMsg, aParam.mClickCount);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool rv;
     paramType::ReasonType reason = 0;
     paramType::ContextMenuTriggerType contextMenuTrigger = 0;
     paramType::ExitFromType exitFrom = 0;
     rv = ReadParam(aMsg, aIter,
                    static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
          ReadParam(aMsg, aIter, &aResult->mIgnoreRootScrollFrame) &&
@@ -267,17 +267,17 @@ struct ParamTraits<mozilla::WidgetDragEv
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
     WriteParam(aMsg, aParam.mUserCancelled);
     WriteParam(aMsg, aParam.mDefaultPreventedOnContent);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool rv =
       ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
       ReadParam(aMsg, aIter, &aResult->mUserCancelled) &&
       ReadParam(aMsg, aIter, &aResult->mDefaultPreventedOnContent);
     return rv;
   }
 };
@@ -293,17 +293,17 @@ struct ParamTraits<mozilla::WidgetPointe
     WriteParam(aMsg, aParam.pointerId);
     WriteParam(aMsg, aParam.width);
     WriteParam(aMsg, aParam.height);
     WriteParam(aMsg, aParam.tiltX);
     WriteParam(aMsg, aParam.tiltY);
     WriteParam(aMsg, aParam.isPrimary);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool rv =
       ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
       ReadParam(aMsg, aIter, &aResult->pointerId) &&
       ReadParam(aMsg, aIter, &aResult->width) &&
       ReadParam(aMsg, aIter, &aResult->height) &&
       ReadParam(aMsg, aIter, &aResult->tiltX) &&
       ReadParam(aMsg, aIter, &aResult->tiltY) &&
@@ -329,17 +329,17 @@ struct ParamTraits<mozilla::WidgetTouchE
       WriteParam(aMsg, touch->mIdentifier);
       WriteParam(aMsg, touch->mRefPoint);
       WriteParam(aMsg, touch->mRadius);
       WriteParam(aMsg, touch->mRotationAngle);
       WriteParam(aMsg, touch->mForce);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     paramType::TouchArray::size_type numTouches;
     if (!ReadParam(aMsg, aIter,
                    static_cast<mozilla::WidgetInputEvent*>(aResult)) ||
         !ReadParam(aMsg, aIter, &numTouches)) {
       return false;
     }
     for (uint32_t i = 0; i < numTouches; ++i) {
@@ -369,17 +369,17 @@ struct ParamTraits<mozilla::AlternativeC
   typedef mozilla::AlternativeCharCode paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mUnshiftedCharCode);
     WriteParam(aMsg, aParam.mShiftedCharCode);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mUnshiftedCharCode) &&
            ReadParam(aMsg, aIter, &aResult->mShiftedCharCode);
   }
 };
 
 
 template<>
@@ -416,17 +416,17 @@ struct ParamTraits<mozilla::WidgetKeyboa
     WriteParam(aMsg, aParam.mNativeCharacters);
     WriteParam(aMsg, aParam.mNativeCharactersIgnoringModifiers);
     WriteParam(aMsg, aParam.mPluginTextEventString);
 #endif
     // An OS-specific native event might be attached in |mNativeKeyEvent|,  but
     // that cannot be copied across process boundaries.
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     mozilla::KeyNameIndexType keyNameIndex = 0;
     mozilla::CodeNameIndexType codeNameIndex = 0;
     paramType::InputMethodAppStateType inputMethodAppState = 0;
     if (ReadParam(aMsg, aIter,
                   static_cast<mozilla::WidgetInputEvent*>(aResult)) &&
         ReadParam(aMsg, aIter, &keyNameIndex) &&
         ReadParam(aMsg, aIter, &codeNameIndex) &&
@@ -472,17 +472,17 @@ struct ParamTraits<mozilla::InternalBefo
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetKeyboardEvent>(aParam));
     WriteParam(aMsg, aParam.mEmbeddedCancelled.IsNull());
     WriteParam(aMsg, aParam.mEmbeddedCancelled.Value());
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool isNull;
     bool value;
     bool rv =
       ReadParam(aMsg, aIter,
                 static_cast<mozilla::WidgetKeyboardEvent*>(aResult)) &&
       ReadParam(aMsg, aIter, &isNull) &&
       ReadParam(aMsg, aIter, &value);
@@ -506,17 +506,17 @@ struct ParamTraits<mozilla::TextRangeSty
     WriteParam(aMsg, aParam.mDefinedStyles);
     WriteParam(aMsg, aParam.mLineStyle);
     WriteParam(aMsg, aParam.mIsBoldLine);
     WriteParam(aMsg, aParam.mForegroundColor);
     WriteParam(aMsg, aParam.mBackgroundColor);
     WriteParam(aMsg, aParam.mUnderlineColor);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mDefinedStyles) &&
            ReadParam(aMsg, aIter, &aResult->mLineStyle) &&
            ReadParam(aMsg, aIter, &aResult->mIsBoldLine) &&
            ReadParam(aMsg, aIter, &aResult->mForegroundColor) &&
            ReadParam(aMsg, aIter, &aResult->mBackgroundColor) &&
            ReadParam(aMsg, aIter, &aResult->mUnderlineColor);
   }
@@ -530,17 +530,17 @@ struct ParamTraits<mozilla::TextRange>
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mStartOffset);
     WriteParam(aMsg, aParam.mEndOffset);
     WriteParam(aMsg, aParam.mRangeType);
     WriteParam(aMsg, aParam.mRangeStyle);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mStartOffset) &&
            ReadParam(aMsg, aIter, &aResult->mEndOffset) &&
            ReadParam(aMsg, aIter, &aResult->mRangeType) &&
            ReadParam(aMsg, aIter, &aResult->mRangeStyle);
   }
 };
 
@@ -552,17 +552,17 @@ struct ParamTraits<mozilla::TextRangeArr
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.Length());
     for (uint32_t index = 0; index < aParam.Length(); index++) {
       WriteParam(aMsg, aParam[index]);
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     paramType::size_type length;
     if (!ReadParam(aMsg, aIter, &length)) {
       return false;
     }
     for (uint32_t index = 0; index < length; index++) {
       mozilla::TextRange textRange;
       if (!ReadParam(aMsg, aIter, &textRange)) {
@@ -587,17 +587,17 @@ struct ParamTraits<mozilla::WidgetCompos
     WriteParam(aMsg, aParam.mNativeIMEContext);
     bool hasRanges = !!aParam.mRanges;
     WriteParam(aMsg, hasRanges);
     if (hasRanges) {
       WriteParam(aMsg, *aParam.mRanges.get());
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     bool hasRanges;
     if (!ReadParam(aMsg, aIter,
                    static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
         !ReadParam(aMsg, aIter, &aResult->mData) ||
         !ReadParam(aMsg, aIter, &aResult->mNativeIMEContext) ||
         !ReadParam(aMsg, aIter, &hasRanges)) {
       return false;
@@ -622,17 +622,17 @@ struct ParamTraits<mozilla::FontRange>
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mStartOffset);
     WriteParam(aMsg, aParam.mFontName);
     WriteParam(aMsg, aParam.mFontSize);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mStartOffset) &&
            ReadParam(aMsg, aIter, &aResult->mFontName) &&
            ReadParam(aMsg, aIter, &aResult->mFontSize);
   }
 };
 
 template<>
@@ -653,17 +653,17 @@ struct ParamTraits<mozilla::WidgetQueryC
     WriteParam(aMsg, aParam.mReply.mString);
     WriteParam(aMsg, aParam.mReply.mRect);
     WriteParam(aMsg, aParam.mReply.mReversed);
     WriteParam(aMsg, aParam.mReply.mHasSelection);
     WriteParam(aMsg, aParam.mReply.mWidgetIsHit);
     WriteParam(aMsg, aParam.mReply.mFontRanges);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mSucceeded) &&
            ReadParam(aMsg, aIter, &aResult->mUseNativeLineBreak) &&
            ReadParam(aMsg, aIter, &aResult->mWithFontRanges) &&
            ReadParam(aMsg, aIter, &aResult->mInput.mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mInput.mLength) &&
@@ -689,17 +689,17 @@ struct ParamTraits<mozilla::WidgetSelect
     WriteParam(aMsg, aParam.mOffset);
     WriteParam(aMsg, aParam.mLength);
     WriteParam(aMsg, aParam.mReversed);
     WriteParam(aMsg, aParam.mExpandToClusterBoundary);
     WriteParam(aMsg, aParam.mSucceeded);
     WriteParam(aMsg, aParam.mUseNativeLineBreak);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mLength) &&
            ReadParam(aMsg, aIter, &aResult->mReversed) &&
            ReadParam(aMsg, aIter, &aResult->mExpandToClusterBoundary) &&
            ReadParam(aMsg, aIter, &aResult->mSucceeded) &&
@@ -712,34 +712,34 @@ struct ParamTraits<nsIMEUpdatePreference
 {
   typedef nsIMEUpdatePreference paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mWantUpdates);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mWantUpdates);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::widget::NativeIMEContext>
 {
   typedef mozilla::widget::NativeIMEContext paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mRawNativeIMEContext);
     WriteParam(aMsg, aParam.mOriginProcessID);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mRawNativeIMEContext) &&
            ReadParam(aMsg, aIter, &aResult->mOriginProcessID);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::widget::IMENotification::Point>
@@ -747,17 +747,17 @@ struct ParamTraits<mozilla::widget::IMEN
   typedef mozilla::widget::IMENotification::Point paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mX);
     WriteParam(aMsg, aParam.mY);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mX) &&
            ReadParam(aMsg, aIter, &aResult->mY);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::widget::IMENotification::Rect>
@@ -767,17 +767,17 @@ struct ParamTraits<mozilla::widget::IMEN
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mX);
     WriteParam(aMsg, aParam.mY);
     WriteParam(aMsg, aParam.mWidth);
     WriteParam(aMsg, aParam.mHeight);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mX) &&
            ReadParam(aMsg, aIter, &aResult->mY) &&
            ReadParam(aMsg, aIter, &aResult->mWidth) &&
            ReadParam(aMsg, aIter, &aResult->mHeight);
   }
 };
 
@@ -793,17 +793,17 @@ struct ParamTraits<mozilla::widget::IMEN
     WriteParam(aMsg, *aParam.mString);
     WriteParam(aMsg, aParam.mWritingMode);
     WriteParam(aMsg, aParam.mReversed);
     WriteParam(aMsg, aParam.mCausedByComposition);
     WriteParam(aMsg, aParam.mCausedBySelectionEvent);
     WriteParam(aMsg, aParam.mOccurredDuringComposition);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     aResult->mString = new nsString();
     return ReadParam(aMsg, aIter, &aResult->mOffset) &&
            ReadParam(aMsg, aIter, aResult->mString) &&
            ReadParam(aMsg, aIter, &aResult->mWritingMode) &&
            ReadParam(aMsg, aIter, &aResult->mReversed) &&
            ReadParam(aMsg, aIter, &aResult->mCausedByComposition) &&
            ReadParam(aMsg, aIter, &aResult->mCausedBySelectionEvent) &&
@@ -821,17 +821,17 @@ struct ParamTraits<mozilla::widget::IMEN
     WriteParam(aMsg, aParam.mStartOffset);
     WriteParam(aMsg, aParam.mRemovedEndOffset);
     WriteParam(aMsg, aParam.mAddedEndOffset);
     WriteParam(aMsg, aParam.mCausedOnlyByComposition);
     WriteParam(aMsg, aParam.mIncludingChangesDuringComposition);
     WriteParam(aMsg, aParam.mIncludingChangesWithoutComposition);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mStartOffset) &&
            ReadParam(aMsg, aIter, &aResult->mRemovedEndOffset) &&
            ReadParam(aMsg, aIter, &aResult->mAddedEndOffset) &&
            ReadParam(aMsg, aIter, &aResult->mCausedOnlyByComposition) &&
            ReadParam(aMsg, aIter,
                      &aResult->mIncludingChangesDuringComposition) &&
            ReadParam(aMsg, aIter,
@@ -850,17 +850,17 @@ struct ParamTraits<mozilla::widget::IMEN
     WriteParam(aMsg, aParam.mOffset);
     WriteParam(aMsg, aParam.mCursorPos);
     WriteParam(aMsg, aParam.mCharRect);
     WriteParam(aMsg, aParam.mButton);
     WriteParam(aMsg, aParam.mButtons);
     WriteParam(aMsg, aParam.mModifiers);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mEventMessage) &&
            ReadParam(aMsg, aIter, &aResult->mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mCursorPos) &&
            ReadParam(aMsg, aIter, &aResult->mCharRect) &&
            ReadParam(aMsg, aIter, &aResult->mButton) &&
            ReadParam(aMsg, aIter, &aResult->mButtons) &&
            ReadParam(aMsg, aIter, &aResult->mModifiers);
@@ -886,17 +886,17 @@ struct ParamTraits<mozilla::widget::IMEN
       case mozilla::widget::NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
         WriteParam(aMsg, aParam.mMouseButtonEventData);
         return;
       default:
         return;
     }
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     mozilla::widget::IMEMessageType IMEMessage = 0;
     if (!ReadParam(aMsg, aIter, &IMEMessage)) {
       return false;
     }
     aResult->mMessage = static_cast<mozilla::widget::IMEMessage>(IMEMessage);
     switch (aResult->mMessage) {
       case mozilla::widget::NOTIFY_IME_OF_SELECTION_CHANGE:
@@ -917,17 +917,17 @@ struct ParamTraits<mozilla::WidgetPlugin
   typedef mozilla::WidgetPluginEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
     WriteParam(aMsg, aParam.mRetargetToFocusedDocument);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mRetargetToFocusedDocument);
   }
 };
 
 template<>
@@ -935,17 +935,17 @@ struct ParamTraits<mozilla::WritingMode>
 {
   typedef mozilla::WritingMode paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mWritingMode);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mWritingMode);
   }
 };
 
 template<>
 struct ParamTraits<mozilla::ContentCache>
 {
@@ -963,17 +963,17 @@ struct ParamTraits<mozilla::ContentCache
     WriteParam(aMsg, aParam.mFirstCharRect);
     WriteParam(aMsg, aParam.mCaret.mOffset);
     WriteParam(aMsg, aParam.mCaret.mRect);
     WriteParam(aMsg, aParam.mTextRectArray.mStart);
     WriteParam(aMsg, aParam.mTextRectArray.mRects);
     WriteParam(aMsg, aParam.mEditorRect);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mText) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mAnchor) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mFocus) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mWritingMode) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mAnchorCharRect) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mFocusCharRect) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mRect) &&
@@ -993,17 +993,17 @@ struct ParamTraits<mozilla::widget::Cand
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mPoint);
     WriteParam(aMsg, aParam.mRect);
     WriteParam(aMsg, aParam.mExcludeRect);
   }
 
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mPoint) &&
            ReadParam(aMsg, aIter, &aResult->mRect) &&
            ReadParam(aMsg, aIter, &aResult->mExcludeRect);
   }
 };
 
 } // namespace IPC