IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, const IonFrameIterator &frame) : IonFrameIterator(activations), machine_(frame.machineState()) { returnAddressToFp_ = frame.returnAddressToFp(); topIonScript_ = frame.ionScript(); const OsiIndex *osiIndex = frame.osiIndex(); current_ = (uint8_t *) frame.fp(); type_ = IonFrame_OptimizedJS; topFrameSize_ = frame.frameSize(); snapshotOffset_ = osiIndex->snapshotOffset(); }
static void MarkIonJSFrame(JSTracer *trc, const IonFrameIterator &frame) { // Currently, this code only executes in sequential execution. CompileMode compileMode = COMPILE_MODE_SEQ; IonJSFrameLayout *layout = (IonJSFrameLayout *)frame.fp(); MarkCalleeToken(trc, layout->calleeToken()); IonScript *ionScript; if (frame.checkInvalidation(&ionScript)) { // This frame has been invalidated, meaning that its IonScript is no // longer reachable through the callee token (JSFunction/JSScript->ion // is now NULL or recompiled). Manually trace it here. IonScript::Trace(trc, ionScript); } else if (CalleeTokenIsFunction(layout->calleeToken())) { ionScript = CalleeTokenToFunction(layout->calleeToken())->script()->ions[compileMode]; } else { ionScript = CalleeTokenToScript(layout->calleeToken())->ions[compileMode]; } if (CalleeTokenIsFunction(layout->calleeToken())) { // (NBP) We do not need to mark formal arguments since they are covered // by the safepoint. size_t nargs = frame.numActualArgs(); // Trace function arguments. Note + 1 for thisv. Value *argv = layout->argv(); for (size_t i = 0; i < nargs + 1; i++) gc::MarkValueRoot(trc, &argv[i], "ion-argv"); } const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp()); SafepointReader safepoint(ionScript, si); // Scan through slots which contain pointers (or on punboxing systems, // actual values). uint32 slot; while (safepoint.getGcSlot(&slot)) { uintptr_t *ref = layout->slotRef(slot); gc::MarkGCThingRoot(trc, reinterpret_cast<void **>(ref), "ion-gc-slot"); } while (safepoint.getValueSlot(&slot)) { Value *v = (Value *)layout->slotRef(slot); gc::MarkValueRoot(trc, v, "ion-gc-slot"); } uintptr_t *spill = frame.spillBase(); GeneralRegisterSet gcRegs = safepoint.gcSpills(); GeneralRegisterSet valueRegs = safepoint.valueSpills(); for (GeneralRegisterIterator iter(safepoint.allSpills()); iter.more(); iter++) { --spill; if (gcRegs.has(*iter)) gc::MarkGCThingRoot(trc, reinterpret_cast<void **>(spill), "ion-gc-spill"); else if (valueRegs.has(*iter)) gc::MarkValueRoot(trc, reinterpret_cast<Value *>(spill), "ion-value-spill"); } #ifdef JS_NUNBOX32 LAllocation type, payload; while (safepoint.getNunboxSlot(&type, &payload)) { jsval_layout layout; layout.s.tag = (JSValueTag)ReadAllocation(frame, &type); layout.s.payload.uintptr = ReadAllocation(frame, &payload); Value v = IMPL_TO_JSVAL(layout); gc::MarkValueRoot(trc, &v, "ion-torn-value"); JS_ASSERT(v == IMPL_TO_JSVAL(layout)); } #endif }