void WorkerThread::handleParseWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(state.canStartParseTask()); JS_ASSERT(idle()); parseTask = state.parseWorklist.popCopy(); parseTask->cx->setWorkerThread(this); { AutoUnlockWorkerThreadState unlock(runtime); parseTask->script = frontend::CompileScript(parseTask->cx, &parseTask->alloc, NullPtr(), NullPtr(), parseTask->options, parseTask->chars, parseTask->length); } // The callback is invoked while we are still off the main thread. parseTask->callback(parseTask->script, parseTask->callbackData); // FinishOffThreadScript will need to be called on the script to // migrate it into the correct compartment. state.parseFinishedList.append(parseTask); parseTask = NULL; // Notify the main thread in case it is waiting for the parse/emit to finish. state.notify(WorkerThreadState::MAIN); }
void WorkerThread::handleIonWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(state.canStartIonCompile()); JS_ASSERT(idle()); ionBuilder = state.ionWorklist.popCopy(); DebugOnly<jit::ExecutionMode> executionMode = ionBuilder->info().executionMode(); JS_ASSERT(GetIonScript(ionBuilder->script(), executionMode) == ION_COMPILING_SCRIPT); state.unlock(); { jit::IonContext ictx(runtime, ionBuilder->script()->compartment(), &ionBuilder->temp()); ionBuilder->setBackgroundCodegen(jit::CompileBackEnd(ionBuilder)); } state.lock(); FinishOffThreadIonCompile(ionBuilder); ionBuilder = NULL; // Notify the main thread in case it is waiting for the compilation to finish. state.notify(WorkerThreadState::MAIN); // Ping the main thread so that the compiled code can be incorporated // at the next operation callback. Don't interrupt Ion code for this, as // this incorporation can be delayed indefinitely without affecting // performance as long as the main thread is actually executing Ion code. runtime->triggerOperationCallback(JSRuntime::TriggerCallbackAnyThreadDontStopIon); }
void WorkerThread::handleIonWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(state.canStartIonCompile()); JS_ASSERT(idle()); ionBuilder = state.ionWorklist.popCopy(); DebugOnly<ion::ExecutionMode> executionMode = ionBuilder->info().executionMode(); JS_ASSERT(GetIonScript(ionBuilder->script(), executionMode) == ION_COMPILING_SCRIPT); state.unlock(); { ion::IonContext ictx(runtime, ionBuilder->script()->compartment(), &ionBuilder->temp()); ionBuilder->setBackgroundCodegen(ion::CompileBackEnd(ionBuilder)); } state.lock(); FinishOffThreadIonCompile(ionBuilder); ionBuilder = NULL; // Notify the main thread in case it is waiting for the compilation to finish. state.notify(WorkerThreadState::MAIN); // Ping the main thread so that the compiled code can be incorporated // at the next operation callback. runtime->triggerOperationCallback(); }
void WorkerThread::handleAsmJSWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(state.canStartAsmJSCompile()); JS_ASSERT(idle()); asmData = state.asmJSWorklist.popCopy(); bool success = false; state.unlock(); do { jit::IonContext icx(runtime, asmData->mir->compartment, &asmData->mir->temp()); int64_t before = PRMJ_Now(); if (!OptimizeMIR(asmData->mir)) break; asmData->lir = GenerateLIR(asmData->mir); if (!asmData->lir) break; int64_t after = PRMJ_Now(); asmData->compileTime = (after - before) / PRMJ_USEC_PER_MSEC; success = true; } while(0); state.lock(); // On failure, signal parent for harvesting in CancelOutstandingJobs(). if (!success) { asmData = NULL; state.noteAsmJSFailure(asmData->func); state.notify(WorkerThreadState::MAIN); return; } // On success, move work to the finished list. state.asmJSFinishedList.append(asmData); asmData = NULL; // Notify the main thread in case it's blocked waiting for a LifoAlloc. state.notify(WorkerThreadState::MAIN); }
void WorkerThread::handleCompressionWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(state.canStartCompressionTask()); JS_ASSERT(idle()); compressionTask = state.compressionWorklist.popCopy(); compressionTask->workerThread = this; { AutoUnlockWorkerThreadState unlock(runtime); if (!compressionTask->compress()) compressionTask->setOOM(); } compressionTask->workerThread = NULL; compressionTask = NULL; // Notify the main thread in case it is waiting for the compression to finish. state.notify(WorkerThreadState::MAIN); }
void WorkerThread::handleParseWorkload(WorkerThreadState &state) { JS_ASSERT(state.isLocked()); JS_ASSERT(!state.parseWorklist.empty()); JS_ASSERT(idle()); parseTask = state.parseWorklist.popCopy(); parseTask->cx->setWorkerThread(this); { AutoUnlockWorkerThreadState unlock(runtime); parseTask->script = frontend::CompileScript(parseTask->cx, &parseTask->alloc, NullPtr(), NullPtr(), parseTask->options, parseTask->chars, parseTask->length); } state.parseFinishedList.append(parseTask); parseTask = NULL; // Notify the main thread in case it is waiting for the parse/emit to finish. state.notify(WorkerThreadState::MAIN); }