Bug 792652 - Move toplevel actor map to IToplevelProtocol (r=dvander)
authorBill McCloskey <billm@mozilla.com>
Tue, 01 Nov 2016 20:55:23 -0700
changeset 351819 b6feaf5672e0d2876e9dc58f5a5e1f219bb2b52a
parent 351818 56e30c8c735bd5ccb75a68a507f8a2e73a0271b3
child 351820 85c13e8c3b6101db8624fbd8931a503bbf9459ff
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs792652
milestone52.0a1
Bug 792652 - Move toplevel actor map to IToplevelProtocol (r=dvander)
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/ipdl/ipdl/lower.py
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -505,17 +505,18 @@ IProtocol::DeallocShmem(Shmem& aMem)
 #endif // DEBUG
   aMem.forget(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead());
   return ok;
 }
 
 IToplevelProtocol::IToplevelProtocol(ProtocolId aProtoId, Side aSide)
  : IProtocol(aSide),
    mProtocolId(aProtoId),
-   mOtherPid(mozilla::ipc::kInvalidProcessId)
+   mOtherPid(mozilla::ipc::kInvalidProcessId),
+   mLastRouteId(mSide == ParentSide : 1 : 0)
 {
 }
 
 IToplevelProtocol::~IToplevelProtocol()
 {
   if (mTrans) {
     RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTrans.release());
     XRE_GetIOMessageLoop()->PostTask(task.forget());
@@ -577,10 +578,38 @@ IToplevelProtocol::SetReplyTimeoutMs(int
 }
 
 bool
 IToplevelProtocol::IsOnCxxStack() const
 {
   return GetIPCChannel()->IsOnCxxStack();
 }
 
+int32_t
+IToplevelProtocol::Register(IProtocol* aRouted)
+{
+  int32_t id = mSide == ParentSide ? ++mLastRouteId : --mLastRouteId;
+  mActorMap.AddWithID(aRouted, id);
+  return id;
+}
+
+int32_t
+IToplevelProtocol::RegisterID(IProtocol* aRouted,
+                              int32_t aId)
+{
+  mActorMap.AddWithID(aRouted, aId);
+  return aId;
+}
+
+IProtocol*
+IToplevelProtocol::Lookup(int32_t aId)
+{
+  return mActorMap.Lookup(aId);
+}
+
+void
+IToplevelProtocol::Unregister(int32_t aId)
+{
+  return mActorMap.Remove(aId);
+}
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -3,16 +3,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ipc_ProtocolUtils_h
 #define mozilla_ipc_ProtocolUtils_h 1
 
+#include "base/id_map.h"
 #include "base/process.h"
 #include "base/process_util.h"
 #include "chrome/common/ipc_message_utils.h"
 
 #include "prenv.h"
 
 #include "IPCMessageStart.h"
 #include "mozilla/Attributes.h"
@@ -250,16 +251,21 @@ public:
     bool Open(MessageChannel* aChannel,
               MessageLoop* aMessageLoop,
               mozilla::ipc::Side aSide = mozilla::ipc::UnknownSide);
 
     void Close();
 
     void SetReplyTimeoutMs(int32_t aTimeoutMs);
 
+    virtual int32_t Register(IProtocol*);
+    virtual int32_t RegisterID(IProtocol*, int32_t);
+    virtual IProtocol* Lookup(int32_t);
+    virtual void Unregister(int32_t);
+
     virtual bool ShouldContinueFromReplyTimeout() {
         return false;
     }
 
     // WARNING: This function is called with the MessageChannel monitor held.
     virtual void IntentionalCrash() {
         MOZ_CRASH("Intentional IPDL crash");
     }
@@ -317,16 +323,18 @@ public:
 
     virtual void ProcessRemoteNativeEventsInInterruptCall() {
     }
 
 private:
     ProtocolId mProtocolId;
     UniquePtr<Transport> mTrans;
     base::ProcessId mOtherPid;
+    IDMap<IProtocol> mActorMap;
+    int32_t mLastRouteId;
 };
 
 class IShmemAllocator
 {
 public:
   virtual bool AllocShmem(size_t aSize,
                           mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
                           mozilla::ipc::Shmem* aShmem) = 0;
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1155,40 +1155,17 @@ class Protocol(ipdl.ast.Protocol):
     def exitedCallVar(self):
         assert self.decl.type.isToplevel()
         return ExprVar('ExitedCall')
 
     def onCxxStackVar(self):
         assert self.decl.type.isToplevel()
         return ExprVar('IsOnCxxStack')
 
-    def nextActorIdExpr(self, side):
-        assert self.decl.type.isToplevel()
-        if side is 'parent':   op = '++'
-        elif side is 'child':  op = '--'
-        else: assert 0
-        return ExprPrefixUnop(self.lastActorIdVar(), op)
-
-    def actorIdInit(self, side):
-        assert self.decl.type.isToplevel()
-
-        # parents go up from FREED, children go down from NULL
-        if side is 'parent':  return _FREED_ACTOR_ID
-        elif side is 'child': return _NULL_ACTOR_ID
-        else: assert 0
-
     # an actor's C++ private variables
-    def lastActorIdVar(self):
-        assert self.decl.type.isToplevel()
-        return ExprVar('mLastRouteId')
-
-    def actorMapVar(self):
-        assert self.decl.type.isToplevel()
-        return ExprVar('mActorMap')
-
     def channelVar(self, actorThis=None):
         if actorThis is not None:
             return ExprSelect(actorThis, '->', 'mChannel')
         return ExprVar('mChannel')
 
     def routingId(self, actorThis=None):
         if self.decl.type.isToplevel():
             return ExprVar('MSG_ROUTING_CONTROL')
@@ -2925,18 +2902,16 @@ class _GenerateProtocolActorCode(ipdl.as
         side = ExprVar('mozilla::ipc::' + self.side.title() + 'Side')
         if ptype.isToplevel():
             ctor.memberinits = [
                 ExprMemberInit(ExprVar('mozilla::ipc::IToplevelProtocol'),
                                [_protocolId(ptype), side]),
                 ExprMemberInit(p.channelVar(), [
                     ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
                              [ ExprVar.THIS ]) ]),
-                ExprMemberInit(p.lastActorIdVar(),
-                               [ p.actorIdInit(self.side) ]),
                 ExprMemberInit(p.lastShmemIdVar(),
                                [ p.shmemIdInit(self.side) ]),
                 ExprMemberInit(p.stateVar(),
                                [ p.startState() ])
             ]
         else:
             ctor.memberinits = [
                 ExprMemberInit(ExprVar('mozilla::ipc::IProtocol'), [side]),
@@ -3334,21 +3309,16 @@ class _GenerateProtocolActorCode(ipdl.as
             deallocself = MethodDefn(MethodDecl(deallocselfvar.name, virtual=1))
             self.cls.addstmts([ deallocself, Whitespace.NL ])
 
         self.implementPickling()
 
         ## private members
         if ptype.isToplevel():
             self.cls.addstmt(StmtDecl(Decl(p.channelType(), 'mChannel')))
-            self.cls.addstmts([
-                StmtDecl(Decl(Type('IDMap', T=Type('ProtocolBase')),
-                              p.actorMapVar().name)),
-                StmtDecl(Decl(_actorIdType(), p.lastActorIdVar().name))
-            ])
         elif ptype.isManaged():
             self.cls.addstmts([
                 StmtDecl(Decl(_actorIdType(), p.idVar().name))
             ])
         if p.decl.type.isToplevel():
             self.cls.addstmts([
                 StmtDecl(Decl(p.shmemMapType(), p.shmemMapVar().name)),
                 StmtDecl(Decl(_shmemIdType(), p.lastShmemIdVar().name))
@@ -3375,35 +3345,16 @@ class _GenerateProtocolActorCode(ipdl.as
         sourcevar = ExprVar('aSource')
         ivar = ExprVar('i')
         kidsvar = ExprVar('kids')
         ithkid = ExprIndex(kidsvar, ivar)
 
         methods = []
 
         if p.decl.type.isToplevel():
-            register = MethodDefn(MethodDecl(
-                p.registerMethod().name,
-                params=[ Decl(protocolbase, routedvar.name) ],
-                ret=_actorIdType(), virtual=1))
-            registerid = MethodDefn(MethodDecl(
-                p.registerIDMethod().name,
-                params=[ Decl(protocolbase, routedvar.name),
-                         Decl(_actorIdType(), idvar.name) ],
-                ret=_actorIdType(),
-                virtual=1))
-            lookup = MethodDefn(MethodDecl(
-                p.lookupIDMethod().name,
-                params=[ Decl(_actorIdType(), idvar.name) ],
-                ret=protocolbase, virtual=1))
-            unregister = MethodDefn(MethodDecl(
-                p.unregisterMethod().name,
-                params=[ Decl(_actorIdType(), idvar.name) ],
-                virtual=1))
-
             createshmem = MethodDefn(MethodDecl(
                 p.createSharedMemory().name,
                 ret=_rawShmemType(ptr=1),
                 params=[ Decl(Type.SIZE, sizevar.name),
                          Decl(_shmemTypeType(), typevar.name),
                          Decl(Type.BOOL, unsafevar.name),
                          Decl(_shmemIdType(ptr=1), idvar.name) ],
                 virtual=1))
@@ -3430,51 +3381,26 @@ class _GenerateProtocolActorCode(ipdl.as
             getchannel.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
 
             getchannelconst = MethodDefn(MethodDecl(
                 p.getChannelMethod().name,
                 ret=Type('MessageChannel', ptr=1, const=1),
                 virtual=1, const=1))
             getchannelconst.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
 
-            methods += [ register,
-                         registerid,
-                         lookup,
-                         unregister,
-                         createshmem,
+            methods += [ createshmem,
                          lookupshmem,
                          istracking,
                          destroyshmem,
                          getchannel,
                          getchannelconst ]
 
         if p.decl.type.isToplevel():
             tmpvar = ExprVar('tmp')
 
-            register.addstmts([
-                StmtDecl(Decl(_actorIdType(), tmpvar.name),
-                         p.nextActorIdExpr(self.side)),
-                StmtExpr(ExprCall(
-                    ExprSelect(p.actorMapVar(), '.', 'AddWithID'),
-                    [ routedvar, tmpvar ])),
-                StmtReturn(tmpvar)
-            ])
-            registerid.addstmts([
-                StmtExpr(
-                    ExprCall(ExprSelect(p.actorMapVar(), '.', 'AddWithID'),
-                             [ routedvar, idvar ])),
-                StmtReturn(idvar)
-            ])
-            lookup.addstmt(StmtReturn(
-                ExprCall(ExprSelect(p.actorMapVar(), '.', 'Lookup'),
-                         [ idvar ])))
-            unregister.addstmt(StmtReturn(
-                ExprCall(ExprSelect(p.actorMapVar(), '.', 'Remove'),
-                         [ idvar ])))
-
             # SharedMemory* CreateSharedMemory(size_t aSize, Type aType, bool aUnsafe, id_t* aId):
             #   RefPtr<SharedMemory> segment(Shmem::Alloc(aSize, aType, aUnsafe));
             #   if (!segment)
             #     return nullptr;
             #   Shmem shmem(segment.get(), [nextshmemid]);
             #   Message descriptor = shmem.ShareTo(subprocess, mId, descriptor);
             #   if (!descriptor)
             #     return nullptr;