Exemple #1
0
    bool invalidateBailedOutScripts() {
        RootedScript script(cx_, fun_->toFunction()->nonLazyScript());

        // Sometimes the script is collected or invalidated already,
        // for example when a full GC runs at an inconvenient time.
        if (!script->hasParallelIonScript()) {
            JS_ASSERT(hasNoPendingInvalidations());
            return true;
        }

        IonScript *ion = script->parallelIonScript();
        JS_ASSERT(pendingInvalidations.length() == ion->parallelInvalidatedScriptEntries());
        Vector<types::RecompileInfo> invalid(cx_);
        for (uint32_t i = 0; i < pendingInvalidations.length(); i++) {
            JSScript *script = pendingInvalidations[i];
            if (script && !hasScript(invalid, script)) {
                JS_ASSERT(script->hasParallelIonScript());
                if (!invalid.append(script->parallelIonScript()->recompileInfo()))
                    return false;
                ion->parallelInvalidatedScriptList()[i] = script;
            }
            pendingInvalidations[i] = NULL;
        }
        Invalidate(cx_, invalid);
        return true;
    }
Exemple #2
0
    virtual bool parallel(ForkJoinSlice &slice) {
#ifndef JS_ION
        JS_NOT_REACHED("Parallel execution without ion");
        return false;
#else
        Spew(SpewOps, "Up");

        // Make a new IonContext for the slice, which is needed if we need to
        // re-enter the VM.
        IonContext icx(cx_, NULL);

        JS_ASSERT(pendingInvalidations[slice.sliceId] == NULL);

        JS_ASSERT(fun_->isFunction());
        RootedFunction callee(cx_, fun_->toFunction());
        if (!callee->nonLazyScript()->hasParallelIonScript()) {
            // Sometimes, particularly with GCZeal, the parallel ion
            // script can be collected between starting the parallel
            // op and reaching this point.  In that case, we just fail
            // and fallback.
            Spew(SpewOps, "Down (Script no longer present)");
            return false;
        }

        ParallelIonInvoke<3> fii(cx_, callee, 3);

        fii.args[0] = Int32Value(slice.sliceId);
        fii.args[1] = Int32Value(slice.numSlices);
        fii.args[2] = BooleanValue(false);

        bool ok = fii.invoke(cx_);
        JS_ASSERT(ok == !slice.abortedScript);
        if (!ok) {
            JSScript *script = slice.abortedScript;
            Spew(SpewBailouts, "Aborted script: %p (hasParallelIonScript? %d)",
                 script, script->hasParallelIonScript());
            JS_ASSERT(script->hasParallelIonScript());
            pendingInvalidations[slice.sliceId] = script;
        }

        Spew(SpewOps, "Down");

        return ok;
#endif // JS_ION
    }
Exemple #3
0
bool
js::ParallelDo::invalidateBailedOutScripts()
{
    RootedScript script(cx_, fun_->toFunction()->nonLazyScript());

    // Sometimes the script is collected or invalidated already,
    // for example when a full GC runs at an inconvenient time.
    if (!script->hasParallelIonScript()) {
        return true;
    }

    Vector<types::RecompileInfo> invalid(cx_);
    for (uint32_t i = 0; i < bailoutRecords.length(); i++) {
        JSScript *script = bailoutRecords[i].topScript;

        // No script to invalidate.
        if (!script || !script->hasParallelIonScript())
            continue;

        switch (bailoutRecords[i].cause) {
          // An interrupt is not the fault of the script, so don't
          // invalidate it.
          case ParallelBailoutInterrupt: continue;

          // An illegal write will not be made legal by invalidation.
          case ParallelBailoutIllegalWrite: continue;

          // For other cases, consider invalidation.
          default: break;
        }

        // Already invalidated.
        if (hasScript(invalid, script))
            continue;

        if (!invalid.append(script->parallelIonScript()->recompileInfo()))
            return false;
    }
    Invalidate(cx_, invalid);
    return true;
}