Bug 1293311 - Handle OOM in ArgumentsObject::finishForIon properly. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 19 Sep 2016 21:04:06 +0200
changeset 314456 d29c970e4d7d1a4f5dccaff860c6eaec60f05856
parent 314455 5a20e1ffb8eae493ac1b6c46e77c376d19a375bb
child 314457 10611fcdd32e0592397302afae63f842359394cb
push id20574
push usercbook@mozilla.com
push dateTue, 20 Sep 2016 10:05:16 +0000
treeherderfx-team@14705f779a46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1293311
milestone51.0a1
Bug 1293311 - Handle OOM in ArgumentsObject::finishForIon properly. r=nbp
js/src/jit/CodeGenerator.cpp
js/src/vm/ArgumentsObject.cpp
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6069,38 +6069,44 @@ CodeGenerator::visitCreateArgumentsObjec
     Register callObj = ToRegister(lir->getCallObject());
     Register temp = ToRegister(lir->temp0());
     Label done;
 
     if (ArgumentsObject* templateObj = lir->mir()->templateObject()) {
         Register objTemp = ToRegister(lir->temp1());
         Register cxTemp = ToRegister(lir->temp2());
 
+        masm.Push(callObj);
+
         // Try to allocate an arguments object. This will leave the reserved
         // slots uninitialized, so it's important we don't GC until we
         // initialize these slots in ArgumentsObject::finishForIon.
         Label failure;
         masm.createGCObject(objTemp, temp, templateObj, gc::DefaultHeap, &failure,
                             /* initContents = */ false);
 
         masm.moveStackPtrTo(temp);
-        masm.addPtr(Imm32(frameSize()), temp);
+        masm.addPtr(Imm32(masm.framePushed()), temp);
 
         masm.setupUnalignedABICall(cxTemp);
         masm.loadJSContext(cxTemp);
         masm.passABIArg(cxTemp);
         masm.passABIArg(temp);
         masm.passABIArg(callObj);
         masm.passABIArg(objTemp);
 
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ArgumentsObject::finishForIon));
-        masm.branchTestPtr(Assembler::Zero, ReturnReg, ReturnReg, masm.exceptionLabel());
+        masm.branchTestPtr(Assembler::Zero, ReturnReg, ReturnReg, &failure);
+
+        // Discard saved callObj on the stack.
+        masm.addToStackPtr(Imm32(sizeof(uintptr_t)));
         masm.jump(&done);
 
         masm.bind(&failure);
+        masm.Pop(callObj);
     }
 
     masm.moveStackPtrTo(temp);
     masm.addPtr(Imm32(frameSize()), temp);
 
     pushArg(callObj);
     pushArg(temp);
     callVM(NewIonArgumentsObjectInfo, lir);
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -378,17 +378,19 @@ ArgumentsObject::finishForIon(JSContext*
     unsigned numActuals = frame->numActualArgs();
     unsigned numFormals = callee->nargs();
     unsigned numArgs = Max(numActuals, numFormals);
     unsigned numBytes = ArgumentsData::bytesRequired(numArgs);
 
     ArgumentsData* data =
         reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
     if (!data) {
-        // Make the object safe for GC.
+        // Make the object safe for GC. Don't report OOM, the slow path will
+        // retry the allocation.
+        cx->recoverFromOutOfMemory();
         obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
         return nullptr;
     }
 
     data->numArgs = numArgs;
     data->rareData = nullptr;
 
     obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));