author | Shu-yu Guo <shu@rfrn.org> |
Fri, 10 Jan 2014 02:25:34 -0800 | |
changeset 162921 | 976a1fe9f0807fa2a93688e9aea9afa4d4506361 |
parent 162920 | 464e261cbcbe791df57a30053f83444519cc30a5 |
child 162922 | 1e4903ca67df1e513ffbd61d3765e07398e778d2 |
push id | 25975 |
push user | ryanvm@gmail.com |
push date | Fri, 10 Jan 2014 19:46:47 +0000 |
treeherder | autoland@e89afc241513 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nmatsakis |
bugs | 919638 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/vm/ForkJoin.cpp +++ b/js/src/vm/ForkJoin.cpp @@ -41,17 +41,18 @@ using mozilla::ThreadLocal; /////////////////////////////////////////////////////////////////////////// // Degenerate configurations // // When JS_THREADSAFE or JS_ION is not defined, we simply run the // |func| callback sequentially. We also forego the feedback // altogether. static bool -ExecuteSequentially(JSContext *cx_, HandleValue funVal, bool *complete, uint16_t numSlices); +ExecuteSequentially(JSContext *cx_, HandleValue funVal, bool *complete, + uint16_t sliceStart, uint16_t numSlices); #if !defined(JS_THREADSAFE) || !defined(JS_ION) bool js::ForkJoin(JSContext *cx, CallArgs &args) { RootedValue argZero(cx, args[0]); bool complete = false; // since warmup is false, will always complete return ExecuteSequentially(cx, argZero, &complete); @@ -145,20 +146,21 @@ js::ParallelTestsShouldPass(JSContext *c #endif // !JS_THREADSAFE || !JS_ION /////////////////////////////////////////////////////////////////////////// // All configurations // // Some code that is shared between degenerate and parallel configurations. static bool -ExecuteSequentially(JSContext *cx, HandleValue funVal, bool *complete, uint16_t numSlices) +ExecuteSequentially(JSContext *cx, HandleValue funVal, bool *complete, + uint16_t sliceStart, uint16_t numSlices) { bool allComplete = true; - for (uint16_t i = 0; i < numSlices; i++) { + for (uint16_t i = sliceStart; i < numSlices; i++) { FastInvokeGuard fig(cx, funVal); InvokeArgs &args = fig.args(); if (!args.init(2)) return false; args.setCallee(funVal); args.setThis(UndefinedValue()); args[0].setInt32(i); args[1].setBoolean(!!cx->runtime()->parallelWarmup); @@ -278,16 +280,17 @@ class ForkJoinOperation }; JSContext *cx_; HandleObject fun_; Vector<ParallelBailoutRecord, 16> bailoutRecords_; AutoScriptVector worklist_; Vector<WorklistData, 16> worklistData_; ForkJoinMode mode_; + uint16_t warmupSlice_; uint16_t numSlices_; TrafficLight enqueueInitialScript(ExecutionStatus *status); TrafficLight compileForParallelExecution(ExecutionStatus *status); TrafficLight warmupExecution(bool stopIfComplete, ExecutionStatus *status); TrafficLight parallelExecution(ExecutionStatus *status); TrafficLight sequentialExecution(bool disqualified, ExecutionStatus *status); @@ -543,16 +546,17 @@ js::ForkJoinOperation::ForkJoinOperation bailoutScript(cx), bailoutBytecode(nullptr), cx_(cx), fun_(fun), bailoutRecords_(cx), worklist_(cx), worklistData_(cx), mode_(mode), + warmupSlice_(0), numSlices_(numSlices) { } ExecutionStatus js::ForkJoinOperation::apply() { ExecutionStatus status; @@ -968,17 +972,17 @@ js::ForkJoinOperation::sequentialExecuti { // XXX use disqualified to set parallelIon to ION_DISABLED_SCRIPT? Spew(SpewOps, "Executing sequential execution (disqualified=%d).", disqualified); bool complete = false; RootedValue funVal(cx_, ObjectValue(*fun_)); - if (!ExecuteSequentially(cx_, funVal, &complete, numSlices_)) + if (!ExecuteSequentially(cx_, funVal, &complete, 0, numSlices_)) return ExecutionFatal; // When invoked without the warmup flag set to true, the kernel // function OUGHT to complete successfully, barring an exception. JS_ASSERT(complete); return ExecutionSequential; } @@ -1126,30 +1130,45 @@ js::ForkJoinOperation::invalidateBailedO } js::ForkJoinOperation::TrafficLight js::ForkJoinOperation::warmupExecution(bool stopIfComplete, ExecutionStatus *status) { // GreenLight: warmup succeeded, still more work to do // RedLight: fatal error or warmup completed all work (check status) - Spew(SpewOps, "Executing warmup."); + Spew(SpewOps, "Executing warmup of slice %u.", warmupSlice_); AutoEnterWarmup warmup(cx_->runtime()); RootedValue funVal(cx_, ObjectValue(*fun_)); bool complete; - if (!ExecuteSequentially(cx_, funVal, &complete, numSlices_)) { + uint32_t warmupTo = Min<uint16_t>(warmupSlice_ + 1, numSlices_); + if (!ExecuteSequentially(cx_, funVal, &complete, warmupSlice_, warmupTo)) { *status = ExecutionFatal; return RedLight; } - if (complete && stopIfComplete) { - Spew(SpewOps, "Warmup execution finished all the work."); - *status = ExecutionWarmup; - return RedLight; + if (complete) { + warmupSlice_ = warmupTo; + if (warmupSlice_ == numSlices_) { + if (stopIfComplete) { + Spew(SpewOps, "Warmup execution finished all the work."); + *status = ExecutionWarmup; + return RedLight; + } + + // If we finished all slices in warmup, be sure check the + // interrupt flag. This is because we won't be running more JS + // code, and thus no more automatic checking of the interrupt + // flag. + if (!js_HandleExecutionInterrupt(cx_)) { + *status = ExecutionFatal; + return RedLight; + } + } } return GreenLight; } js::ForkJoinOperation::TrafficLight js::ForkJoinOperation::parallelExecution(ExecutionStatus *status) {