Bug 1262671 - void** -> PickleIterator (r=froydnj)
authorBill McCloskey <billm@mozilla.com>
Wed, 20 Apr 2016 21:09:15 -0700
changeset 372285 63f6395614e8085c33d552e8c56e312df5c763a3
parent 372284 fff9ee7eaf1072bc237e6eaa48fb4705027cae5b
child 372286 4dc70010565c32f332c7f37eb34706571d690e18
push id19496
push userdmitchell@mozilla.com
push dateFri, 27 May 2016 22:17:17 +0000
reviewersfroydnj
bugs1262671
milestone49.0a1
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