MethodStatus compileForParallelExecution() { // The kernel should be a self-hosted function. if (!fun_->isFunction()) return Method_Skipped; RootedFunction callee(cx_, fun_->toFunction()); if (!callee->isInterpreted() || !callee->isSelfHostedBuiltin()) return Method_Skipped; if (callee->isInterpretedLazy() && !callee->initializeLazyScript(cx_)) return Method_Error; // If this function has not been run enough to enable parallel // execution, perform a warmup. RootedScript script(cx_, callee->nonLazyScript()); if (script->getUseCount() < js_IonOptions.usesBeforeCompileParallel) { if (!warmupForParallelExecution()) return Method_Error; } Spew(SpewOps, "Compiling all reachable functions"); ParallelCompileContext compileContext(cx_); if (!compileContext.appendToWorklist(callee)) return Method_Error; MethodStatus status = compileContext.compileTransitively(); if (status != Method_Compiled) return status; // it can happen that during transitive compilation, our // callee's parallel ion script is invalidated or GC'd. So // before we declare success, double check that it's still // compiled! if (!callee->nonLazyScript()->hasParallelIonScript()) return Method_Skipped; return Method_Compiled; }
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; } 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; } pendingInvalidations[i] = NULL; } Invalidate(cx_, invalid); return true; }