diff --git a/js/src/jit-test/tests/parallel/bug1022948.js b/js/src/jit-test/tests/parallel/bug1022948.js new file mode 100644 index 000000000000..26609610356d --- /dev/null +++ b/js/src/jit-test/tests/parallel/bug1022948.js @@ -0,0 +1,12 @@ +if (!getBuildConfiguration().parallelJS) + quit(0); + +var a = Array.buildPar(999, function() { + return (Math.asin(Math.tanh(1))) +}); +var count = 0; +for (let e of a) { + count++; + print(count); + assertEq(e, a[0]) +} diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index e64a5300b161..5425134081d0 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -1105,26 +1105,22 @@ static JSConstDoubleSpec number_constants[] = { {0,0,0,{0,0,0}} }; -#if (defined __GNUC__ && defined __i386__) || \ - (defined __SUNPRO_CC && defined __i386) - /* * Set the exception mask to mask all exceptions and set the FPU precision * to 53 bit mantissa (64 bit doubles). */ -static inline void FIX_FPU() { +void +js::FIX_FPU() +{ +#if (defined __GNUC__ && defined __i386__) || \ + (defined __SUNPRO_CC && defined __i386) short control; asm("fstcw %0" : "=m" (control) : ); control &= ~0x300; // Lower bits 8 and 9 (precision control). control |= 0x2f3; // Raise bits 0-5 (exception masks) and 9 (64-bit precision). asm("fldcw %0" : : "m" (control) ); -} - -#else - -#define FIX_FPU() ((void)0) - #endif +} bool js::InitRuntimeNumberState(JSRuntime *rt) diff --git a/js/src/jsnum.h b/js/src/jsnum.h index f76ede5c7654..729b4563135c 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -332,6 +332,8 @@ NonObjectToUint32(ThreadSafeContext *cx, const Value &v, uint32_t *out) return NonObjectToUint32Slow(cx, v, out); } +void FIX_FPU(); + } /* namespace js */ #endif /* jsnum_h */ diff --git a/js/src/vm/ThreadPool.cpp b/js/src/vm/ThreadPool.cpp index 3108685d375a..849fbcd721f0 100644 --- a/js/src/vm/ThreadPool.cpp +++ b/js/src/vm/ThreadPool.cpp @@ -9,6 +9,7 @@ #include "mozilla/Atomics.h" #include "jslock.h" +#include "jsnum.h" // for FIX_FPU #include "js/Utility.h" #include "vm/ForkJoin.h" @@ -174,6 +175,10 @@ ThreadPoolWorker::HelperThreadMain(void *arg) } #endif + // Set the FPU control word to be the same as the main thread's, else we + // might get inconsistent results from math functions. + FIX_FPU(); + worker->helperLoop(); }