Bug 1396499 - Part 2: Do not hold reference to expression stack values in GeneratorObject::suspend. r=jandem

This commit is contained in:
Tooru Fujisawa 2017-10-26 22:10:31 +09:00
parent c8f0b1e5a1
commit afdbd65a3b
3 changed files with 14 additions and 10 deletions

View File

@ -4837,22 +4837,23 @@ BaselineCompiler::emit_JSOP_RESUME()
{
masm.unboxObject(exprStackSlot, scratch2);
Register arrayLength = regs.takeAny();
Register initLength = regs.takeAny();
masm.loadPtr(Address(scratch2, NativeObject::offsetOfElements()), scratch2);
masm.load32(Address(scratch2, ObjectElements::offsetOfLength()), arrayLength);
masm.store32(Imm32(0), Address(scratch2, ObjectElements::offsetOfLength()));
masm.load32(Address(scratch2, ObjectElements::offsetOfInitializedLength()), initLength);
masm.store32(Imm32(0), Address(scratch2, ObjectElements::offsetOfInitializedLength()));
Label loop, loopDone;
masm.bind(&loop);
masm.branchTest32(Assembler::Zero, arrayLength, arrayLength, &loopDone);
masm.branchTest32(Assembler::Zero, initLength, initLength, &loopDone);
{
masm.pushValue(Address(scratch2, 0));
masm.guardedCallPreBarrier(Address(scratch2, 0), MIRType::Value);
masm.addPtr(Imm32(sizeof(Value)), scratch2);
masm.sub32(Imm32(1), arrayLength);
masm.sub32(Imm32(1), initLength);
masm.jump(&loop);
}
masm.bind(&loopDone);
regs.add(arrayLength);
regs.add(initLength);
}
masm.bind(&noExprStack);

View File

@ -84,10 +84,13 @@ GeneratorObject::suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame
if (nvalues > 0) {
do {
if (genObj->hasExpressionStack()) {
MOZ_ASSERT(genObj->expressionStack().getDenseInitializedLength() == 0);
auto result = genObj->expressionStack().setOrExtendDenseElements(
cx, 0, vp, nvalues, ShouldUpdateTypes::DontUpdate);
if (result == DenseElementResult::Success)
if (result == DenseElementResult::Success) {
MOZ_ASSERT(genObj->expressionStack().getDenseInitializedLength() == nvalues);
break;
}
if (result == DenseElementResult::Failure)
return false;
}
@ -182,12 +185,12 @@ GeneratorObject::resume(JSContext* cx, InterpreterActivation& activation,
activation.regs().fp()->initArgsObj(genObj->argsObj());
if (genObj->hasExpressionStack() && !genObj->isExpressionStackEmpty()) {
uint32_t len = genObj->expressionStack().length();
uint32_t len = genObj->expressionStack().getDenseInitializedLength();
MOZ_ASSERT(activation.regs().spForStackDepth(len));
const Value* src = genObj->expressionStack().getDenseElements();
mozilla::PodCopy(activation.regs().sp, src, len);
activation.regs().sp += len;
genObj->expressionStack().setLengthInt32(0);
genObj->expressionStack().setDenseInitializedLength(0);
}
JSScript* script = callee->nonLazyScript();

View File

@ -101,7 +101,7 @@ class GeneratorObject : public NativeObject
return getFixedSlot(EXPRESSION_STACK_SLOT).isObject();
}
bool isExpressionStackEmpty() const {
return expressionStack().length() == 0;
return expressionStack().getDenseInitializedLength() == 0;
}
ArrayObject& expressionStack() const {
return getFixedSlot(EXPRESSION_STACK_SLOT).toObject().as<ArrayObject>();