Bug 1297804 - part 1 - eschew array bounds checking in nsTArray IPDL-generated code, reader-side; r=billm
authorNathan Froyd <froydnj@gmail.com>
Fri, 02 Sep 2016 16:14:28 -0400
changeset 312386 ad48a00323b3d435e1b46ff6befbdcce17c61f36
parent 312385 1477881ee551854e3b136225083e8d85a41aca38
child 312387 92bd6c9ee5f54528a5c56b2bbe612e6f9ce7a5b4
push id81366
push usernfroyd@mozilla.com
push dateFri, 02 Sep 2016 12:16:26 +0000
treeherdermozilla-inbound@1b874fea3cbc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1297804
milestone51.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 1297804 - part 1 - eschew array bounds checking in nsTArray IPDL-generated code, reader-side; r=billm For better or worse, the IPDL compiler, for protocols that send or receive arrays, generates Read 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
@@ -4326,16 +4326,26 @@ class _GenerateProtocolActorCode(ipdl.as
         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')
+
         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.addstmt(
             self.checkedWrite(eltipdltype, ExprIndex(var, ivar), msgvar,
                               sentinelKey=arraytype.name()))
@@ -4349,29 +4359,32 @@ class _GenerateProtocolActorCode(ipdl.as
 
         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(favar, ivar)),
+            self.checkedRead(eltipdltype, ExprAddrOf(ExprIndex(elemsvar, ivar)),
                              msgvar, itervar, errfnRead,
                              '\'' + eltipdltype.name() + '[i]\'',
                              sentinelKey=arraytype.name()))
+        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())),
             Whitespace.NL,
-            StmtExpr(_callCxxArraySetLength(favar, lenvar)),
+            appendstmt,
             forread,
             StmtExpr(_callCxxSwapArrayElements(var, favar, '->')),
             StmtReturn.TRUE
         ])
 
         self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])