Bug 1440511 - Part 12: Remove the now-unused per-actor pickling code, r=froydnj
authorNika Layzell <nika@thelayzells.com>
Thu, 22 Feb 2018 18:59:15 -0500
changeset 461680 14c593ecf7259dd98abb81f51bb4dd63edc4ebf9
parent 461679 df74e15398ad0132f2506109e1619cdd40ac31ea
child 461681 d506f9eb0db6d368cd0155d8088e362db64daa41
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1440511
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1440511 - Part 12: Remove the now-unused per-actor pickling code, r=froydnj MozReview-Commit-ID: 5ASQu4ly0od
ipc/glue/Shmem.h
ipc/ipdl/ipdl/lower.py
--- a/ipc/glue/Shmem.h
+++ b/ipc/glue/Shmem.h
@@ -57,17 +57,16 @@ namespace mozilla {
 namespace layers {
 class ShadowLayerForwarder;
 } // namespace layers
 
 namespace ipc {
 
 class Shmem final
 {
-  friend struct IPC::ParamTraits<mozilla::ipc::Shmem>;
   friend struct IPDLParamTraits<mozilla::ipc::Shmem>;
 #ifdef DEBUG
   // For ShadowLayerForwarder::CheckSurfaceDescriptor
   friend class mozilla::layers::ShadowLayerForwarder;
 #endif
 
 public:
   typedef int32_t id_t;
@@ -275,48 +274,9 @@ struct IPDLParamTraits<Shmem>
   {
     aLog->append(L"(shmem segment)");
   }
 };
 
 } // namespace ipc
 } // namespace mozilla
 
-
-namespace IPC {
-
-// NOTE: This will be replaced by IPDLParamTraits, but is needed to keep the old
-// serialization logic working until it is removed. It will be removed in a
-// later part.
-template<>
-struct ParamTraits<mozilla::ipc::Shmem>
-{
-  typedef mozilla::ipc::Shmem paramType;
-
-  // NB: Read()/Write() look creepy in that Shmems have a pointer
-  // 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, PickleIterator* aIter, paramType* aResult)
-  {
-    paramType::id_t id;
-    if (!ReadParam(aMsg, aIter, &id))
-      return false;
-    aResult->mId = id;
-    return true;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-    aLog->append(L"(shmem segment)");
-  }
-};
-
-
-} // namespace IPC
-
-
 #endif // ifndef mozilla_ipc_Shmem_h
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -164,81 +164,16 @@ def _deleteId():
     return ExprVar('Msg___delete____ID')
 
 def _deleteReplyId():
     return ExprVar('Reply___delete____ID')
 
 def _lookupListener(idexpr):
     return ExprCall(ExprVar('Lookup'), args=[ idexpr ])
 
-def _shmemType(ptr=0, const=1, ref=0):
-    return Type('Shmem', ptr=ptr, ref=ref)
-
-def _rawShmemType(ptr=0):
-    return Type('Shmem::SharedMemory', ptr=ptr)
-
-def _shmemIdType(ptr=0):
-    return Type('Shmem::id_t', ptr=ptr)
-
-def _shmemTypeType():
-    return Type('Shmem::SharedMemory::SharedMemoryType')
-
-def _shmemBackstagePass():
-    return ExprCall(ExprVar(
-        'Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead'))
-
-def _shmemCtor(rawmem, idexpr):
-    return ExprCall(ExprVar('Shmem'),
-                    args=[ _shmemBackstagePass(), rawmem, idexpr ])
-
-def _shmemId(shmemexpr):
-    return ExprCall(ExprSelect(shmemexpr, '.', 'Id'),
-                    args=[ _shmemBackstagePass() ])
-
-def _shmemSegment(shmemexpr):
-    return ExprCall(ExprSelect(shmemexpr, '.', 'Segment'),
-                    args=[ _shmemBackstagePass() ])
-
-def _shmemAlloc(size, type, unsafe):
-    # starts out UNprotected
-    return ExprCall(ExprVar('Shmem::Alloc'),
-                    args=[ _shmemBackstagePass(), size, type, unsafe ])
-
-def _shmemDealloc(rawmemvar):
-    return ExprCall(ExprVar('Shmem::Dealloc'),
-                    args=[ _shmemBackstagePass(), rawmemvar ])
-
-def _shmemShareTo(shmemvar, processvar, route):
-    return ExprCall(ExprSelect(shmemvar, '.', 'ShareTo'),
-                    args=[ _shmemBackstagePass(),
-                           processvar, route ])
-
-def _shmemOpenExisting(descriptor, outid):
-    # starts out protected
-    return ExprCall(ExprVar('Shmem::OpenExisting'),
-                    args=[ _shmemBackstagePass(),
-                           # true => protect
-                           descriptor, outid, ExprLiteral.TRUE ])
-
-def _shmemUnshareFrom(shmemvar, processvar, route):
-    return ExprCall(ExprSelect(shmemvar, '.', 'UnshareFrom'),
-                    args=[ _shmemBackstagePass(),
-                           processvar, route ])
-
-def _shmemForget(shmemexpr):
-    return ExprCall(ExprSelect(shmemexpr, '.', 'forget'),
-                    args=[ _shmemBackstagePass() ])
-
-def _shmemRevokeRights(shmemexpr):
-    return ExprCall(ExprSelect(shmemexpr, '.', 'RevokeRights'),
-                    args=[ _shmemBackstagePass() ])
-
-def _lookupShmem(idexpr):
-    return ExprCall(ExprVar('LookupSharedMemory'), args=[ idexpr ])
-
 def _makeForwardDeclForQClass(clsname, quals, cls=1, struct=0):
     fd = ForwardDecl(clsname, cls=cls, struct=struct)
     if 0 == len(quals):
         return fd
 
     outerns = Namespace(quals[0])
     innerns = outerns
     for ns in quals[1:]:
@@ -484,26 +419,16 @@ def errfnSendDtor(msg):
 # used in |OnMessage*()| handlers that hand in-messages off to Recv*()
 # interface methods
 def errfnRecv(msg, errcode=_Result.ValuError):
     return [
         _fatalError(msg),
         StmtReturn(errcode)
     ]
 
-# used in Read() methods
-def errfnRead(msg):
-    return [ _fatalError(msg), StmtReturn.FALSE ]
-
-def errfnArrayLength(elementname):
-    return [ _arrayLengthReadError(elementname), StmtReturn.FALSE ]
-
-def errfnUnionType(unionname):
-    return [ _unionTypeReadError(unionname), StmtReturn.FALSE ]
-
 def errfnSentinel(rvalue=ExprLiteral.FALSE):
     def inner(msg):
         return [ _sentinelReadError(msg), StmtReturn(rvalue) ]
     return inner
 
 def _destroyMethod():
     return ExprVar('ActorDestroy')
 
@@ -3681,18 +3606,16 @@ class _GenerateProtocolActorCode(ipdl.as
         # don't delete outselves: either the manager will do it, or
         # we're toplevel
         self.cls.addstmts([ deallocsubtree, Whitespace.NL ])
 
         if ptype.isToplevel():
             deallocself = MethodDefn(MethodDecl(deallocselfvar.name, methodspec=MethodSpec.VIRTUAL))
             self.cls.addstmts([ deallocself, Whitespace.NL ])
 
-        self.implementPickling()
-
         ## private members
         if ptype.isToplevel():
             self.cls.addstmt(StmtDecl(Decl(p.channelType(), 'mChannel')))
 
         self.cls.addstmt(StmtDecl(Decl(Type('State'), p.stateVar().name)))
 
         for managed in ptype.manages:
             self.cls.addstmts([
@@ -3848,522 +3771,16 @@ class _GenerateProtocolActorCode(ipdl.as
 
 
     ##-------------------------------------------------------------------------
     ## The next few functions are the crux of the IPDL code generator.
     ## They generate code for all the nasty work of message
     ## serialization/deserialization and dispatching handlers for
     ## received messages.
     ##
-    def implementPickling(self):
-        # pickling of "normal", non-IPDL types
-        self.implementGenericPickling()
-
-        # pickling for IPDL types
-        specialtypes = set()
-        class findSpecialTypes(TypeVisitor):
-            def visitActorType(self, a): specialtypes.add(a)
-            def visitShmemType(self, s): specialtypes.add(s)
-            def visitByteBufType(self, s): specialtypes.add(s)
-            def visitFDType(self, s): specialtypes.add(s)
-            def visitStructType(self, s):
-                specialtypes.add(s)
-                return TypeVisitor.visitStructType(self, s)
-            def visitUnionType(self, u):
-                specialtypes.add(u)
-                return TypeVisitor.visitUnionType(self, u)
-            def visitArrayType(self, a):
-                if a.basetype.isIPDL():
-                    specialtypes.add(a)
-                    return a.basetype.accept(self)
-
-        for md in self.protocol.messageDecls:
-            for param in md.params:
-                mtype = md.decl.type
-                # special case for top-level __delete__(), which isn't
-                # understood yet
-                if mtype.isDtor() and mtype.constructedType().isToplevel():
-                    continue
-                param.ipdltype.accept(findSpecialTypes())
-            for ret in md.returns:
-                ret.ipdltype.accept(findSpecialTypes())
-
-        for t in specialtypes:
-            if t.isActor():     self.implementActorPickling(t)
-            elif t.isArray():   self.implementSpecialArrayPickling(t)
-            elif t.isShmem():   self.implementShmemPickling(t)
-            elif t.isByteBuf(): self.implementByteBufPickling(t)
-            elif t.isFD():      self.implementFDPickling(t)
-            elif t.isStruct():  self.implementStructPickling(t)
-            elif t.isUnion():   self.implementUnionPickling(t)
-            else:
-                assert 0 and 'unknown special type'
-
-    def implementGenericPickling(self):
-        var = self.var
-        msgvar = self.msgvar
-        itervar = self.itervar
-
-        write = MethodDefn(self.writeMethodDecl(
-            Type('T', const=1, ref=1), var, template=Type('T')))
-        write.addstmt(StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
-                                        args=[ msgvar, var ])))
-
-        read = MethodDefn(self.readMethodDecl(
-            Type('T', ptr=1), var, template=Type('T')))
-        read.addstmt(StmtReturn(ExprCall(ExprVar('IPC::ReadParam'),
-                                         args=[ msgvar, itervar, var ])))
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-    def implementByteBufPickling(self, bytebuftype):
-        var = self.var
-        msgvar = self.msgvar
-        itervar = self.itervar
-        intype = _cxxRefType(bytebuftype, self.side)
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        write.addstmt(StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
-                                        args=[ msgvar, var ])))
-
-        self.cls.addstmts([ write, Whitespace.NL ])
-        # the rest of generic pickling will work fine for us
-
-    def implementActorPickling(self, actortype):
-        # Note that we pickle based on *protocol* type and *not* actor
-        # type.  The actor type includes a |nullable| qualifier, but
-        # this method is not specialized based on nullability.  The
-        # |actortype| nullability is ignored in this method.
-        var = self.var
-        idvar = ExprVar('id')
-        intype = _cxxConstRefType(actortype, self.side)
-        # XXX the writer code can treat the actor as logically const; many
-        # other places that call _cxxConstRefType cannot treat the actor
-        # as logically const, particularly callers that can leak out to
-        # Gecko directly.
-        intype.const = 1
-        cxxtype = _cxxBareType(actortype, self.side)
-        outtype = _cxxPtrToType(actortype, self.side)
-
-        ## Write([const] PFoo* var)
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        nullablevar = ExprVar('nullable__')
-        write.decl.params.append(Decl(Type.BOOL, nullablevar.name))
-        # id_t id;
-        # if (!var)
-        #   if(!nullable)
-        #     abort()
-        #   id = NULL_ID
-        write.addstmt(StmtDecl(Decl(_actorIdType(), idvar.name)))
-
-        ifnull = StmtIf(ExprNot(var))
-        ifnotnullable = StmtIf(ExprNot(nullablevar))
-        ifnotnullable.addifstmt(
-            _fatalError("NULL actor value passed to non-nullable param"))
-        ifnull.addifstmt(ifnotnullable)
-        ifnull.addifstmt(StmtExpr(ExprAssn(idvar, _NULL_ACTOR_ID)))
-        # else
-        #   id = var->mId
-        #   if (id == FREED_ID)
-        #     abort()
-        # Write(msg, id)
-        ifnull.addelsestmt(StmtExpr(ExprAssn(idvar, _actorId(var))))
-        iffreed = StmtIf(ExprBinary(_FREED_ACTOR_ID, '==', idvar))
-        # this is always a hard-abort, because it means that some C++
-        # code has a live pointer to a freed actor, so we're playing
-        # Russian roulette with invalid memory
-        iffreed.addifstmt(_fatalError("actor has been |delete|d"))
-        ifnull.addelsestmt(iffreed)
-
-        write.addstmts([
-            ifnull,
-            Whitespace.NL,
-            StmtExpr(self.write(None, idvar, self.msgvar))
-        ])
-
-        ## Read(PFoo** var)
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-        read.decl.params.append(Decl(Type.BOOL, nullablevar.name))
-
-        actorvar = ExprVar('actor')
-        read.addstmts([
-            StmtDecl(Decl(Type('Maybe', T=Type('mozilla::ipc::IProtocol', ptr=1)), actorvar.name),
-                     init=ExprCall(ExprVar('ReadActor'),
-                                   args=[ self.msgvar, self.itervar, nullablevar,
-                                          ExprLiteral.String(actortype.name()),
-                                          _protocolId(actortype) ])),
-        ])
-
-        # if (actor.isNothing())
-        #   return false
-        #
-        # Reading the actor failed in some way, and the appropriate error was raised.
-        ifnothing = StmtIf(ExprCall(ExprSelect(actorvar, '.', 'isNothing')))
-        ifnothing.addifstmts([
-            StmtReturn.FALSE,
-        ])
-
-        read.addstmts([ ifnothing, Whitespace.NL ])
-
-        read.addstmts([
-                StmtExpr(ExprAssn(ExprDeref(var),
-                                  ExprCast(ExprCall(ExprSelect(actorvar, '.', 'value')), cxxtype, static=1))),
-                StmtReturn.TRUE
-        ])
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-
-    def implementSpecialArrayPickling(self, arraytype):
-        var = self.var
-        msgvar = self.msgvar
-        itervar = self.itervar
-        lenvar = ExprVar('length')
-        ivar = ExprVar('i')
-        eltipdltype = arraytype.basetype
-        intype = _cxxConstRefType(arraytype, self.side)
-        outtype = _cxxPtrToType(arraytype, self.side)
-
-        # We access elements directly in Read and Write to avoid array bounds
-        # checking.
-        directtype = _cxxBareType(arraytype.basetype, self.side)
-        if directtype.ptr:
-            typeinit = { 'ptrptr': 1 }
-        else:
-            typeinit = { 'ptr': 1 }
-        directtype = Type(directtype.name, **typeinit)
-        elemsvar = ExprVar('elems')
-        elemvar = ExprVar('elem')
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        forwrite = StmtRangedFor(elemvar, var)
-        forwrite.addstmt(
-            self.checkedWrite(eltipdltype, elemvar, msgvar,
-                              sentinelKey=arraytype.name()))
-        write.addstmts([
-            StmtDecl(Decl(Type.UINT32, lenvar.name),
-                     init=_callCxxArrayLength(var)),
-            self.checkedWrite(None, lenvar, msgvar, sentinelKey=('length', arraytype.name())),
-            Whitespace.NL,
-            forwrite
-        ])
-
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-        favar = ExprVar('fa')
-        forread = StmtFor(init=ExprAssn(Decl(Type.UINT32, ivar.name),
-                                        ExprLiteral.ZERO),
-                          cond=ExprBinary(ivar, '<', lenvar),
-                          update=ExprPrefixUnop(ivar, '++'))
-        forread.addstmt(
-            self.checkedRead(eltipdltype, ExprAddrOf(ExprIndex(elemsvar, ivar)),
-                             msgvar, itervar, errfnRead,
-                             '\'' + eltipdltype.name() + '[i]\'',
-                             sentinelKey=arraytype.name(),
-                             errfnSentinel=errfnSentinel()))
-        appendstmt = StmtDecl(Decl(directtype, elemsvar.name),
-                              init=ExprCall(ExprSelect(favar, '.', 'AppendElements'),
-                                            args=[ lenvar ]))
-        read.addstmts([
-            StmtDecl(Decl(_cxxArrayType(_cxxBareType(arraytype.basetype, self.side)), favar.name)),
-            StmtDecl(Decl(Type.UINT32, lenvar.name)),
-            self.checkedRead(None, ExprAddrOf(lenvar),
-                             msgvar, itervar, errfnArrayLength,
-                             [ arraytype.name() ],
-                             sentinelKey=('length', arraytype.name()),
-                             errfnSentinel=errfnSentinel()),
-            Whitespace.NL,
-            appendstmt,
-            forread,
-            StmtExpr(_callCxxSwapArrayElements(var, favar, '->')),
-            StmtReturn.TRUE
-        ])
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-
-    def implementShmemPickling(self, shmemtype):
-        msgvar = self.msgvar
-        itervar = self.itervar
-        var = self.var
-        tmpvar = ExprVar('tmp')
-        idvar = ExprVar('shmemid')
-        rawvar = ExprVar('rawmem')
-        baretype = _cxxBareType(shmemtype, self.side)
-        intype = _cxxConstRefType(shmemtype, self.side)
-        outtype = _cxxPtrToType(shmemtype, self.side)
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        write.addstmts([
-            StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
-                              args=[ msgvar, var ])),
-            StmtExpr(_shmemRevokeRights(var)),
-            StmtExpr(_shmemForget(var))
-        ])
-
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-        ifread = StmtIf(ExprNot(ExprCall(ExprVar('IPC::ReadParam'),
-                                         args=[ msgvar, itervar,
-                                                ExprAddrOf(tmpvar) ])))
-        ifread.addifstmt(StmtReturn.FALSE)
-
-        iffound = StmtIf(rawvar)
-        iffound.addifstmt(StmtExpr(ExprAssn(
-            ExprDeref(var), _shmemCtor(rawvar, idvar))))
-        iffound.addifstmt(StmtReturn.TRUE)
-
-        read.addstmts([
-            StmtDecl(Decl(_shmemType(), tmpvar.name)),
-            ifread,
-            Whitespace.NL,
-            StmtDecl(Decl(_shmemIdType(), idvar.name),
-                     init=_shmemId(tmpvar)),
-            StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name),
-                     init=_lookupShmem(idvar)),
-            iffound,
-            # This is ugly: we failed to look the shmem up, most likely because
-            # we failed to map it the first time it was deserialized. we create
-            # an empty shmem and let the user of the shmem deal with it.
-            # if we returned false here we would crash.
-            StmtExpr(ExprAssn(ExprDeref(var), ExprCall(ExprVar('Shmem'), args=[]) )),
-            StmtReturn.TRUE
-        ])
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-    def implementFDPickling(self, fdtype):
-        msgvar = self.msgvar
-        itervar = self.itervar
-        var = self.var
-        tmpvar = ExprVar('fd')
-        picklevar = ExprVar('pfd')
-        intype = _cxxConstRefType(fdtype, self.side)
-        outtype = _cxxPtrToType(fdtype, self.side)
-
-        def _fdType():
-            return Type('FileDescriptor')
-
-        def _fdPickleType():
-            return Type('FileDescriptor::PickleType')
-
-        def _fdBackstagePass():
-            return ExprCall(ExprVar('FileDescriptor::IPDLPrivate'))
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        write.addstmts([
-            StmtDecl(Decl(_fdPickleType(), picklevar.name),
-                     init=ExprCall(ExprSelect(var, '.', 'ShareTo'),
-                                   args=[ _fdBackstagePass(),
-                                          self.protocol.callOtherPid() ])),
-            StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
-                              args=[ msgvar, picklevar ])),
-        ])
-
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-        ifread = StmtIf(ExprNot(ExprCall(ExprVar('IPC::ReadParam'),
-                                         args=[ msgvar, itervar,
-                                                ExprAddrOf(picklevar) ])))
-        ifread.addifstmt(StmtReturn.FALSE)
-
-        ifnvalid = StmtIf(ExprNot(ExprCall(ExprSelect(tmpvar, '.', 'IsValid'))))
-        ifnvalid.addifstmt(
-            _protocolErrorBreakpoint('[' +
-                                     _actorName(self.protocol.name, self.side) +
-                                     '] Received an invalid file descriptor!'))
-
-        read.addstmts([
-            StmtDecl(Decl(_fdPickleType(), picklevar.name)),
-            ifread,
-            Whitespace.NL,
-            StmtDecl(Decl(_fdType(), tmpvar.name),
-                     init=ExprCall(ExprVar('FileDescriptor'),
-                                   args=[ _fdBackstagePass(), picklevar ])),
-            ifnvalid,
-            Whitespace.NL,
-            StmtExpr(ExprAssn(ExprDeref(var), tmpvar)),
-            StmtReturn.TRUE
-        ])
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-    def implementStructPickling(self, structtype):
-        msgvar = self.msgvar
-        itervar = self.itervar
-        var = self.var
-        intype = _cxxConstRefType(structtype, self.side)
-        outtype = _cxxPtrToType(structtype, self.side)
-        sd = structtype._ast
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-
-        def get(sel, f):
-            return ExprCall(f.getMethod(thisexpr=var, sel=sel))
-
-        for f in sd.fields:
-            desc = '\'' + f.getMethod().name + '\' (' + f.ipdltype.name() + \
-                   ') member of \'' + intype.name + '\''
-            writefield = self.checkedWrite(f.ipdltype, get('.', f), msgvar, sentinelKey=f.basename)
-            readfield = self.checkedRead(f.ipdltype,
-                                         ExprAddrOf(get('->', f)),
-                                         msgvar, itervar, errfnRead, desc,
-                                         sentinelKey=f.basename, errfnSentinel=errfnSentinel())
-            if f.special and f.side != self.side:
-                writefield = Whitespace(
-                    "// skipping actor field that's meaningless on this side\n", indent=1)
-                readfield = Whitespace(
-                    "// skipping actor field that's meaningless on this side\n", indent=1)
-            write.addstmt(writefield)
-            read.addstmt(readfield)
-
-        read.addstmt(StmtReturn.TRUE)
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-
-    def implementUnionPickling(self, uniontype):
-        msgvar = self.msgvar
-        itervar = self.itervar
-        var = self.var
-        intype = _cxxConstRefType(uniontype, self.side)
-        outtype = _cxxPtrToType(uniontype, self.side)
-        ud = uniontype._ast
-
-        typename = 'type__'
-        uniontdef = Typedef(_cxxBareType(uniontype, typename), typename)
-
-        typevar = ExprVar('type')
-        writeswitch = StmtSwitch(ud.callType(var))
-        readswitch = StmtSwitch(typevar)
-
-        for c in ud.components:
-            ct = c.ipdltype
-            isactor = (ct.isIPDL() and ct.isActor())
-            caselabel = CaseLabel(typename +'::'+ c.enum())
-            origenum = c.enum()
-
-            writecase = StmtBlock()
-            if c.special and c.side != self.side:
-                writecase.addstmt(_fatalError('wrong side!'))
-            else:
-                wexpr = ExprCall(ExprSelect(var, '.', c.getTypeName()))
-                writecase.addstmt(self.checkedWrite(ct, wexpr, msgvar, sentinelKey=c.enum()))
-
-            writecase.addstmt(StmtReturn())
-            writeswitch.addcase(caselabel, writecase)
-
-            readcase = StmtBlock()
-            if c.special and c.side == self.side:
-                # the type comes across flipped from what the actor
-                # will be on this side; i.e. child->parent messages
-                # have type PFooChild when received on the parent side
-                # XXX: better error message
-                readcase.addstmt(StmtReturn.FALSE)
-            else:
-                if c.special:
-                    c = c.other       # see above
-                tmpvar = ExprVar('tmp')
-                ct = c.bareType()
-                readcase.addstmts([
-                    StmtDecl(Decl(ct, tmpvar.name), init=c.defaultValue()),
-                    StmtExpr(ExprAssn(ExprDeref(var), tmpvar)),
-                    self.checkedRead(
-                        c.ipdltype,
-                        ExprAddrOf(ExprCall(ExprSelect(var, '->',
-                                                       c.getTypeName()))),
-                        msgvar, itervar, errfnRead, 'Union type',
-                        sentinelKey=origenum, errfnSentinel=errfnSentinel()),
-                    StmtReturn(ExprLiteral.TRUE)
-                ])
-
-            readswitch.addcase(caselabel, readcase)
-
-        unknowntype = 'unknown union type'
-        writeswitch.addcase(DefaultLabel(),
-                            StmtBlock([ _fatalError(unknowntype),
-                                        StmtReturn() ]))
-        readswitch.addcase(DefaultLabel(), StmtBlock(errfnRead(unknowntype)))
-
-        write = MethodDefn(self.writeMethodDecl(intype, var))
-        write.addstmts([
-            uniontdef,
-            self.checkedWrite(
-                None, ExprCall(Type.INT, args=[ ud.callType(var) ]), msgvar,
-                sentinelKey=uniontype.name()),
-            Whitespace.NL,
-            writeswitch
-        ])
-
-        read = MethodDefn(self.readMethodDecl(outtype, var))
-        read.addstmts([
-            uniontdef,
-            StmtDecl(Decl(Type.INT, typevar.name)),
-            self.checkedRead(
-                None, ExprAddrOf(typevar), msgvar, itervar, errfnUnionType,
-                [ uniontype.name() ],
-                sentinelKey=uniontype.name(), errfnSentinel=errfnSentinel()),
-            Whitespace.NL,
-            readswitch,
-        ])
-
-        self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
-
-
-    def writeMethodDecl(self, intype, var, template=None):
-        return MethodDecl(
-            'Write',
-            params=[ Decl(intype, var.name),
-                     Decl(Type('Message', ptr=1), self.msgvar.name) ],
-            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(_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)
-            else:
-                call.args.append(ExprLiteral.FALSE)
-        return call
-
-    def write(self, ipdltype, expr, to, this=None):
-        write = ExprVar('Write')
-        if this:  write = ExprSelect(this, '->', write.name)
-        return self.maybeAddNullabilityArg(ipdltype,
-                                           ExprCall(write, args=[ expr, to ]))
-
-    def read(self, ipdltype, expr, from_, iterexpr, this=None):
-        read = ExprVar('Read')
-        if this:  read = ExprSelect(this, '->', read.name)
-        return self.maybeAddNullabilityArg(
-            ipdltype, ExprCall(read, args=[ expr, from_, iterexpr ]))
-
-    def checkedWrite(self, ipdltype, expr, msgvar, sentinelKey, this=None):
-        assert sentinelKey
-
-        write = StmtExpr(self.write(ipdltype, expr, msgvar, this))
-
-        sentinel = StmtExpr(ExprCall(ExprSelect(msgvar, '->', 'WriteSentinel'),
-                                     args=[ ExprLiteral.Int(hashfunc(sentinelKey)) ]))
-        block = Block()
-        block.addstmts([
-            write,
-            Whitespace('// Sentinel = ' + repr(sentinelKey) + '\n', indent=1),
-            sentinel ])
-        return block
-
-
     def visitMessageDecl(self, md):
         isctor = md.decl.type.isCtor()
         isdtor = md.decl.type.isDtor()
         decltype = md.decl.type
         sendmethod = None
         promisesendmethod = None
         helpermethod = None
         recvlbl, recvcase = None, None
@@ -5305,40 +4722,16 @@ class _GenerateProtocolActorCode(ipdl.as
         if actor is not None:  stateexpr = _actorState(actor)
         else:                  stateexpr = self.protocol.stateVar()
 
         msgid = md.pqMsgId() if not reply else md.pqReplyId()
         return [ StmtExpr(ExprCall(ExprVar(self.protocol.name +'::Transition'),
                                    args=[ ExprVar(msgid),
                                    ExprAddrOf(stateexpr) ])) ]
 
-    def checkedRead(self, ipdltype, expr, msgexpr, iterexpr, errfn, paramtype, sentinelKey, errfnSentinel, sentinel=True):
-        ifbad = StmtIf(ExprNot(self.read(ipdltype, expr, msgexpr, iterexpr)))
-        if isinstance(paramtype, list):
-            errorcall = errfn(*paramtype)
-            senterrorcall = errfnSentinel(*paramtype)
-        else:
-            errorcall = errfn('Error deserializing ' + paramtype)
-            senterrorcall = errfnSentinel('Error deserializing ' + paramtype)
-        ifbad.addifstmts(errorcall)
-
-        block = Block()
-        block.addstmt(ifbad)
-
-        if sentinel:
-            assert sentinelKey
-            block.addstmt(Whitespace('// Sentinel = ' + repr(sentinelKey) + '\n', indent=1))
-            read = ExprCall(ExprSelect(msgexpr, '->', 'ReadSentinel'),
-                                  args=[ iterexpr, ExprLiteral.Int(hashfunc(sentinelKey)) ])
-            ifsentinel = StmtIf(ExprNot(read))
-            ifsentinel.addifstmts(senterrorcall)
-            block.addstmt(ifsentinel)
-
-        return block
-
     def endRead(self, msgexpr, iterexpr):
         msgtype = ExprCall(ExprSelect(msgexpr, '.', 'type'), [ ])
         return StmtExpr(ExprCall(ExprSelect(msgexpr, '.', 'EndRead'),
                                  args=[ iterexpr, msgtype ]))
 
 class _GenerateProtocolParentCode(_GenerateProtocolActorCode):
     def __init__(self):
         _GenerateProtocolActorCode.__init__(self, 'parent')