Bug 1297804 - part 2 - eschew array bounds checking in nsTArray IPDL-generated code, writer-side; r=billm
authorNathan Froyd <froydnj@gmail.com>
Fri, 02 Sep 2016 16:14:28 -0400
changeset 312413 92bd6c9ee5f54528a5c56b2bbe612e6f9ce7a5b4
parent 312412 ad48a00323b3d435e1b46ff6befbdcce17c61f36
child 312414 af44291ba592257c4ced0a91ba77ca448bb6bb42
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1297804
milestone51.0a1
Bug 1297804 - part 2 - eschew array bounds checking in nsTArray IPDL-generated code, writer-side; r=billm For better or worse, the IPDL compiler, for protocols that send or receive arrays, generates Write methods for transferring those arrays, rather than going through the standard ParamTraits specializations. These generated methods perform unnecessary bounds checks when accessing elements; such checks can be safely bypassed because we know the exact length of all the arrays involved. (Some compilers are not smart enough to eliminate the bounds checks on their own.)
ipc/ipdl/ipdl/lower.py
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -4244,16 +4244,21 @@ class _GenerateProtocolActorCode(ipdl.as
     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;
@@ -4335,24 +4340,22 @@ class _GenerateProtocolActorCode(ipdl.as
         # 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 = StmtFor(init=ExprAssn(Decl(Type.UINT32, ivar.name),
-                                         ExprLiteral.ZERO),
-                           cond=ExprBinary(ivar, '<', lenvar),
-                           update=ExprPrefixUnop(ivar, '++'))
+        forwrite = StmtRangedFor(elemvar, var)
         forwrite.addstmt(
-            self.checkedWrite(eltipdltype, ExprIndex(var, ivar), msgvar,
+            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
         ])