Пример #1
0
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
}