bool MResumePoint::writeRecoverData(CompactBufferWriter &writer) const { writer.writeUnsigned(uint32_t(RInstruction::Recover_ResumePoint)); MBasicBlock *bb = block(); JSFunction *fun = bb->info().funMaybeLazy(); JSScript *script = bb->info().script(); uint32_t exprStack = stackDepth() - bb->info().ninvoke(); #ifdef DEBUG // Ensure that all snapshot which are encoded can safely be used for // bailouts. if (GetIonContext()->cx) { uint32_t stackDepth; bool reachablePC; jsbytecode *bailPC = pc(); if (mode() == MResumePoint::ResumeAfter) bailPC = GetNextPc(pc()); if (!ReconstructStackDepth(GetIonContext()->cx, script, bailPC, &stackDepth, &reachablePC)) { return false; } if (reachablePC) { if (JSOp(*bailPC) == JSOP_FUNCALL) { // For fun.call(this, ...); the reconstructStackDepth will // include the this. When inlining that is not included. So the // exprStackSlots will be one less. MOZ_ASSERT(stackDepth - exprStack <= 1); } else if (JSOp(*bailPC) != JSOP_FUNAPPLY && !IsGetPropPC(bailPC) && !IsSetPropPC(bailPC)) { // For fun.apply({}, arguments) the reconstructStackDepth will // have stackdepth 4, but it could be that we inlined the // funapply. In that case exprStackSlots, will have the real // arguments in the slots and not be 4. // With accessors, we have different stack depths depending on // whether or not we inlined the accessor, as the inlined stack // contains a callee function that should never have been there // and we might just be capturing an uneventful property site, // in which case there won't have been any violence. MOZ_ASSERT(exprStack == stackDepth); } } } #endif // Test if we honor the maximum of arguments at all times. This is a sanity // check and not an algorithm limit. So check might be a bit too loose. +4 // to account for scope chain, return value, this value and maybe // arguments_object. MOZ_ASSERT(CountArgSlots(script, fun) < SNAPSHOT_MAX_NARGS + 4); uint32_t implicit = StartArgSlot(script); uint32_t formalArgs = CountArgSlots(script, fun); uint32_t nallocs = formalArgs + script->nfixed() + exprStack; IonSpew(IonSpew_Snapshots, "Starting frame; implicit %u, formals %u, fixed %u, exprs %u", implicit, formalArgs - implicit, script->nfixed(), exprStack); uint32_t pcoff = script->pcToOffset(pc()); IonSpew(IonSpew_Snapshots, "Writing pc offset %u, nslots %u", pcoff, nallocs); writer.writeUnsigned(pcoff); writer.writeUnsigned(nallocs); return true; }
bool MRegExpExec::writeRecoverData(CompactBufferWriter& writer) const { MOZ_ASSERT(canRecoverOnBailout()); writer.writeUnsigned(uint32_t(RInstruction::Recover_RegExpExec)); return true; }