Bug 967167 - Use fallible memory allocation when reading IPDL array types to make sure that we don't OOM for very large arrays; r=bent
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Thu, 06 Feb 2014 08:35:28 -0500
changeset 167232 160e1cbe2fcf33092d6df068be5ffd94c0545d73
parent 167231 e3b700ce10fcca3c4e78799fdc9baaf2c0bee73f
child 167233 c3530d73e8fe246e364b8337eea3ba0a762e47bd
push id39404
push usereakhgari@mozilla.com
push dateThu, 06 Feb 2014 13:35:36 +0000
treeherdermozilla-inbound@160e1cbe2fcf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs967167
milestone30.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 967167 - Use fallible memory allocation when reading IPDL array types to make sure that we don't OOM for very large arrays; r=bent
ipc/ipdl/ipdl/lower.py
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -326,22 +326,32 @@ def _autoptrGet(expr):
     return ExprCall(ExprSelect(expr, '.', 'get'))
 
 def _autoptrForget(expr):
     return ExprCall(ExprSelect(expr, '.', 'forget'))
 
 def _cxxArrayType(basetype, const=0, ref=0):
     return Type('InfallibleTArray', T=basetype, const=const, ref=ref)
 
+def _cxxFallibleArrayType(basetype, const=0, ref=0):
+    return Type('FallibleTArray', T=basetype, const=const, ref=ref)
+
 def _callCxxArrayLength(arr):
     return ExprCall(ExprSelect(arr, '.', 'Length'))
 
-def _callCxxArraySetLength(arr, lenexpr, sel='.'):
-    return ExprCall(ExprSelect(arr, sel, 'SetLength'),
-                    args=[ lenexpr ])
+def _callCxxCheckedArraySetLength(arr, lenexpr, sel='.'):
+    ifbad = StmtIf(ExprNot(ExprCall(ExprSelect(arr, sel, 'SetLength'),
+                                    args=[ lenexpr ])))
+    ifbad.addifstmt(_fatalError('Error setting the array length'))
+    ifbad.addifstmt(StmtReturn.FALSE)
+    return ifbad
+
+def _callCxxSwapArrayElements(arr1, arr2, sel='.'):
+    return ExprCall(ExprSelect(arr1, sel, 'SwapElements'),
+                    args=[ arr2 ])
 
 def _callCxxArrayInsertSorted(arr, elt):
     return ExprCall(ExprSelect(arr, '.', 'InsertElementSorted'),
                     args=[ elt ])
 
 def _callCxxArrayRemoveSorted(arr, elt):
     return ExprCall(ExprSelect(arr, '.', 'RemoveElementSorted'),
                     args=[ elt ])
@@ -4454,36 +4464,36 @@ class _GenerateProtocolActorCode(ipdl.as
             StmtDecl(Decl(Type.UINT32, lenvar.name),
                      init=_callCxxArrayLength(var)),
             StmtExpr(self.write(None, lenvar, msgvar)),
             Whitespace.NL,
             forwrite
         ])
 
         read = MethodDefn(self.readMethodDecl(outtype, var))
-        avar = ExprVar('a')
+        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(avar, ivar)),
+            self.checkedRead(eltipdltype, ExprAddrOf(ExprIndex(favar, ivar)),
                              msgvar, itervar, errfnRead,
                              eltipdltype.name() + '[i]'))
         read.addstmts([
-            StmtDecl(Decl(_cxxRefType(arraytype, self.side), avar.name),
-                     init=ExprDeref(var)),
+            StmtDecl(Decl(_cxxFallibleArrayType(_cxxBareType(arraytype.basetype, self.side)), favar.name)),
             StmtDecl(Decl(Type.UINT32, lenvar.name)),
             self.checkedRead(None, ExprAddrOf(lenvar),
                              msgvar, itervar, errfnRead,
                              'length\' (' + Type.UINT32.name + ') of \'' +
                              arraytype.name()),
             Whitespace.NL,
-            StmtExpr(_callCxxArraySetLength(var, lenvar, '->')),
+            _callCxxCheckedArraySetLength(favar, lenvar),
             forread,
+            StmtExpr(_callCxxSwapArrayElements(var, favar, '->')),
             StmtReturn.TRUE
         ])
 
         self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
 
 
     def implementShmemPickling(self, shmemtype):
         msgvar = self.msgvar