Bug 1262463 - part 3 - out-of-line NS_RUNTIMEABORT calls in IPDL-generated code; r=jld
authorNathan Froyd <froydnj.com>
Wed, 06 Apr 2016 10:53:06 -0400
changeset 316006 0e3178883b513cafb9167e8ac994d1d6fb3fba32
parent 316005 c829fb88558b35ab5a0ff29e28faeb0cb7316ab8
child 316007 42154de581f72b32b3247db33c764221d86573a8
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld
bugs1262463
milestone48.0a1
Bug 1262463 - part 3 - out-of-line NS_RUNTIMEABORT calls in IPDL-generated code; r=jld We do this for the same reasons outlined in part 1: calls to NS_RUNTIMEABORT are rather large and we generate a lot of them (~1000 left after part 1). This patch reduces .text size by ~20K on x86-64 Linux.
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/ipdl/ipdl/lower.py
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -366,10 +366,16 @@ FatalError(const char* aProtocolName, co
 #endif
     MOZ_CRASH("IPC FatalError in the parent process!");
   } else {
     formattedMessage.AppendLiteral("\". abort()ing as a result.");
     NS_RUNTIMEABORT(formattedMessage.get());
   }
 }
 
+void
+LogicError(const char* aMsg)
+{
+  NS_RUNTIMEABORT(aMsg);
+}
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -305,19 +305,29 @@ MOZ_NEVER_INLINE void
 LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
                       const char* aContextDescription,
                       const char* aMessageDescription,
                       MessageDirection aDirection);
 
 MOZ_NEVER_INLINE void
 ProtocolErrorBreakpoint(const char* aMsg);
 
+// The code generator calls this function for errors which come from the
+// methods of protocols.  Doing this saves codesize by making the error
+// cases significantly smaller.
 MOZ_NEVER_INLINE void
 FatalError(const char* aProtocolName, const char* aMsg, bool aIsParent);
 
+// The code generator calls this function for errors which are not
+// protocol-specific: errors in generated struct methods or errors in
+// transition functions, for instance.  Doing this saves codesize by
+// by making the error cases significantly smaller.
+MOZ_NEVER_INLINE void
+LogicError(const char* aMsg);
+
 struct PrivateIPDLInterface {};
 
 nsresult
 Bridge(const PrivateIPDLInterface&,
        MessageChannel*, base::ProcessId, MessageChannel*, base::ProcessId,
        ProtocolId, ProtocolId);
 
 bool
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -309,22 +309,16 @@ function would return true for |Actor[]|
                  or (ipdltype.isArray()
                      and _hasVisibleActor(ipdltype.basetype))))
 
 def _abortIfFalse(cond, msg):
     return StmtExpr(ExprCall(
         ExprVar('MOZ_DIAGNOSTIC_ASSERT'),
         [ cond, ExprLiteral.String(msg) ]))
 
-def _runtimeAbort(msg):
-    if isinstance(msg, str):
-        msg = ExprLiteral.String(msg)
-    return StmtExpr(
-        ExprCall(ExprVar('NS_RUNTIMEABORT'), args=[ msg ]))
-
 def _refptr(T):
     return Type('RefPtr', T=T)
 
 def _refptrGet(expr):
     return ExprCall(ExprSelect(expr, '.', 'get'))
 
 def _refptrForget(expr):
     return ExprCall(ExprSelect(expr, '.', 'forget'))
@@ -412,16 +406,20 @@ def _printWarningMessage(msg):
         msg = ExprLiteral.String(msg)
     return StmtExpr(
         ExprCall(ExprVar('NS_WARNING'), args=[ msg ]))
 
 def _fatalError(msg):
     return StmtExpr(
         ExprCall(ExprVar('FatalError'), args=[ ExprLiteral.String(msg) ]))
 
+def _logicError(msg):
+    return StmtExpr(
+        ExprCall(ExprVar('mozilla::ipc::LogicError'), args=[ ExprLiteral.String(msg) ]))
+
 def _killProcess(pid):
     return ExprCall(
         ExprVar('base::KillProcess'),
         args=[ pid,
                # XXX this is meaningless on POSIX
                ExprVar('base::PROCESS_END_KILLED_BY_USER'),
                ExprLiteral.FALSE ])
 
@@ -1841,38 +1839,38 @@ class _GenerateProtocolCode(ipdl.ast.Vis
         nullerrorblock.addstmt(
             StmtReturn(ExprBinary(_nullState(), '==', fromvar)))
         fromswitch.addfallthrough(CaseLabel(_nullState().name))
         fromswitch.addcase(CaseLabel(_errorState().name), nullerrorblock)
 
         # special case for Dead
         deadblock = Block()
         deadblock.addstmts([
-            _runtimeAbort('__delete__()d actor'),
+            _logicError('__delete__()d actor'),
             StmtReturn(ExprLiteral.FALSE) ])
         fromswitch.addcase(CaseLabel(_deadState().name), deadblock)
 
         # special case for Dying
         dyingblock = Block()
         if ptype.hasReentrantDelete:
             ifdelete = StmtIf(ExprBinary(_deleteReplyId(), '==', msgexpr))
             ifdelete.addifstmt(
                 StmtExpr(ExprAssn(ExprDeref(nextvar), _deadState())))
             dyingblock.addstmt(ifdelete)
             dyingblock.addstmt(
                 StmtReturn(ExprLiteral.TRUE))
         else:
             dyingblock.addstmts([
-                _runtimeAbort('__delete__()d (and unexpectedly dying) actor'),
+                _logicError('__delete__()d (and unexpectedly dying) actor'),
                 StmtReturn(ExprLiteral.FALSE) ])
         fromswitch.addcase(CaseLabel(_dyingState().name), dyingblock)
 
         unreachedblock = Block()
         unreachedblock.addstmts([
-            _runtimeAbort('corrupted actor state'),
+            _logicError('corrupted actor state'),
             StmtReturn(ExprLiteral.FALSE) ])
         fromswitch.addcase(DefaultLabel(), unreachedblock)
 
         if usesend:
             transitionfunc.addstmt(
                 StmtDecl(Decl(Type('int32_t', const=1), sendvar.name),
                          init=ExprVar('mozilla::ipc::Trigger::Send')))
         if userecv:
@@ -2279,17 +2277,17 @@ def _generateCxxUnion(ud):
     dtorswitch = StmtSwitch(mtypevar)
     for c in ud.components:
         dtorswitch.addcase(
             CaseLabel(c.enum()),
             StmtBlock([ StmtExpr(c.callDtor()),
                         StmtBreak() ]))
     dtorswitch.addcase(
         DefaultLabel(),
-        StmtBlock([ _runtimeAbort("not reached"), StmtBreak() ]))
+        StmtBlock([ _logicError("not reached"), StmtBreak() ]))
     maybedtor.addstmts([
         ifnone,
         ifnochange,
         dtorswitch,
         StmtReturn.TRUE
     ])
     cls.addstmts([ maybedtor, Whitespace.NL ])
 
@@ -2350,17 +2348,17 @@ def _generateCxxUnion(ud):
                     ExprCall(ExprSelect(othervar,
                                         '.', c.getConstTypeName())))),
                 StmtBreak()
             ]))
     copyswitch.addcase(CaseLabel(tnonevar.name),
                        StmtBlock([ StmtBreak() ]))
     copyswitch.addcase(
         DefaultLabel(),
-        StmtBlock([ _runtimeAbort('unreached'), StmtReturn() ]))
+        StmtBlock([ _logicError('unreached'), StmtReturn() ]))
     copyctor.addstmts([
         StmtExpr(callAssertSanity(uvar=othervar)),
         copyswitch,
         StmtExpr(ExprAssn(mtypevar, othertype))
     ])
     cls.addstmts([ copyctor, Whitespace.NL ])
 
     # ~Union()
@@ -2406,17 +2404,17 @@ def _generateCxxUnion(ud):
             StmtBreak()
         ])
         opeqswitch.addcase(CaseLabel(c.enum()), case)
     opeqswitch.addcase(CaseLabel(tnonevar.name),
                        StmtBlock([ StmtExpr(callMaybeDestroy(rhstypevar)),
                                    StmtBreak() ]))
     opeqswitch.addcase(
         DefaultLabel(),
-        StmtBlock([ _runtimeAbort('unreached'), StmtBreak() ]))
+        StmtBlock([ _logicError('unreached'), StmtBreak() ]))
     opeq.addstmts([
         StmtExpr(callAssertSanity(uvar=rhsvar)),
         StmtDecl(Decl(typetype, rhstypevar.name), init=ud.callType(rhsvar)),
         opeqswitch,
         StmtExpr(ExprAssn(mtypevar, rhstypevar)),
         StmtReturn(ExprDeref(ExprVar.THIS))
     ])
     cls.addstmts([ opeq, Whitespace.NL ])
@@ -2447,17 +2445,17 @@ def _generateCxxUnion(ud):
     for c in ud.components:
         case = StmtBlock()
         case.addstmt(StmtReturn(ExprBinary(
             ExprCall(ExprVar(c.getTypeName())), '==',
             ExprCall(ExprSelect(rhsvar, '.', c.getTypeName())))))
         opeqeqswitch.addcase(CaseLabel(c.enum()), case)
     opeqeqswitch.addcase(
         DefaultLabel(),
-        StmtBlock([ _runtimeAbort('unreached'),
+        StmtBlock([ _logicError('unreached'),
                     StmtReturn.FALSE ]))
     opeqeq.addstmt(opeqeqswitch)
 
     cls.addstmts([ opeqeq, Whitespace.NL ])
 
     # accessors for each type: operator T&, operator const T&,
     # T& get(), const T& get()
     for c in ud.components: