Esempio n. 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;
    }
Esempio n. 2
0
 inline bool hasNoPendingInvalidations() {
     for (uint32_t i = 0; i < pendingInvalidations.length(); i++) {
         if (pendingInvalidations[i] != NULL)
             return false;
     }
     return true;
 }
Esempio n. 3
0
    ExecutionStatus apply() {
        SpewBeginOp(cx_, "ParallelDo");

        if (!ion::IsEnabled(cx_))
            return SpewEndOp(disqualifyFromParallelExecution());

        if (!pendingInvalidations.resize(ForkJoinSlices(cx_)))
            return SpewEndOp(ExecutionFatal);

        // Try to execute in parallel.  If a bailout occurs, re-warmup
        // and then try again.  Repeat this a few times.
        while (bailouts < MAX_BAILOUTS) {
            MethodStatus status = compileForParallelExecution();
            if (status == Method_Error)
                return SpewEndOp(ExecutionFatal);
            if (status != Method_Compiled)
                return SpewEndOp(disqualifyFromParallelExecution());

            ParallelResult result = js::ExecuteForkJoinOp(cx_, *this);
            switch (result) {
              case TP_RETRY_SEQUENTIALLY:
                Spew(SpewBailouts, "Bailout not categorized");
                break;

              case TP_SUCCESS:
                return SpewEndOp(ExecutionParallel);

              case TP_FATAL:
                return SpewEndOp(ExecutionFatal);
            }

            bailouts += 1;
            SpewBailout(bailouts);

            if (!invalidateBailedOutScripts())
                return SpewEndOp(ExecutionFatal);

            if (!warmupForParallelExecution())
                return SpewEndOp(ExecutionFatal);
        }

        // After enough tries, just execute sequentially.
        return SpewEndOp(disqualifyFromParallelExecution());
    }