зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1031529 part 2 - Remove JS_THREADSAFE #ifdefs everywhere. r=bhackett
This commit is contained in:
Родитель
24bccfb24b
Коммит
9dd0f57269
|
@ -17,11 +17,7 @@
|
|||
|
||||
struct JSPrincipals {
|
||||
/* Don't call "destroy"; use reference counting macros below. */
|
||||
#ifdef JS_THREADSAFE
|
||||
mozilla::Atomic<int32_t> refcount;
|
||||
#else
|
||||
int32_t refcount;
|
||||
#endif
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
/* A helper to facilitate principals debugging. */
|
||||
|
|
|
@ -123,11 +123,7 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp)
|
|||
if (!JS_SetProperty(cx, info, "has-gczeal", value))
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
value = BooleanValue(false);
|
||||
#endif
|
||||
if (!JS_SetProperty(cx, info, "threadsafe", value))
|
||||
return false;
|
||||
|
||||
|
@ -1605,14 +1601,10 @@ static bool
|
|||
HelperThreadCount(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
#ifdef JS_THREADSAFE
|
||||
if (CanUseExtraThreads())
|
||||
args.rval().setInt32(HelperThreadState().threadCount);
|
||||
else
|
||||
args.rval().setInt32(0);
|
||||
#else
|
||||
args.rval().setInt32(0);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
#ifndef JSGC_GENERATIONAL
|
||||
#error "JSGC_GENERATIONAL is required for the ForkJoinNursery"
|
||||
#endif
|
||||
#ifndef JS_THREADSAFE
|
||||
#error "JS_THREADSAFE is required for the ForkJoinNursery"
|
||||
#endif
|
||||
#ifndef JS_ION
|
||||
#error "JS_ION is required for the ForkJoinNursery"
|
||||
#endif
|
||||
|
|
|
@ -86,22 +86,18 @@ struct ConservativeGCData
|
|||
}
|
||||
|
||||
~ConservativeGCData() {
|
||||
#ifdef JS_THREADSAFE
|
||||
/*
|
||||
* The conservative GC scanner should be disabled when the thread leaves
|
||||
* the last request.
|
||||
*/
|
||||
JS_ASSERT(!hasStackToScan());
|
||||
#endif
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE void recordStackTop();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void updateForRequestEnd() {
|
||||
nativeStackTop = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasStackToScan() const {
|
||||
return !!nativeStackTop;
|
||||
|
@ -193,9 +189,7 @@ class GCRuntime
|
|||
// Internal public interface
|
||||
js::gc::State state() { return incrementalState; }
|
||||
void recordNativeStackTop();
|
||||
#ifdef JS_THREADSAFE
|
||||
void notifyRequestEnd() { conservativeGC.updateForRequestEnd(); }
|
||||
#endif
|
||||
bool isBackgroundSweeping() { return helperState.isBackgroundSweeping(); }
|
||||
void waitBackgroundSweepEnd() { helperState.waitBackgroundSweepEnd(); }
|
||||
void waitBackgroundSweepOrAllocEnd() { helperState.waitBackgroundSweepOrAllocEnd(); }
|
||||
|
@ -207,37 +201,27 @@ class GCRuntime
|
|||
bool onBackgroundThread() { return helperState.onBackgroundThread(); }
|
||||
|
||||
bool currentThreadOwnsGCLock() {
|
||||
#ifdef JS_THREADSAFE
|
||||
return lockOwner == PR_GetCurrentThread();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void assertCanLock() {
|
||||
JS_ASSERT(!currentThreadOwnsGCLock());
|
||||
}
|
||||
#endif
|
||||
|
||||
void lockGC() {
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(lock);
|
||||
JS_ASSERT(!lockOwner);
|
||||
#ifdef DEBUG
|
||||
lockOwner = PR_GetCurrentThread();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void unlockGC() {
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(lockOwner == PR_GetCurrentThread());
|
||||
lockOwner = nullptr;
|
||||
PR_Unlock(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -346,9 +346,7 @@ gc::GCRuntime::markConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
|
|||
#endif
|
||||
|
||||
if (!conservativeGC.hasStackToScan()) {
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!rt->requestDepth);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5487,8 +5487,6 @@ CheckFunctionsSequential(ModuleCompiler &m)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
// Currently, only one asm.js parallel compilation is allowed at a time.
|
||||
// This RAII class attempts to claim this parallel compilation using atomic ops
|
||||
// on the helper thread state's asmJSCompilationInProgress.
|
||||
|
@ -5739,7 +5737,6 @@ CheckFunctionsParallel(ModuleCompiler &m)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
static bool
|
||||
CheckFuncPtrTable(ModuleCompiler &m, ParseNode *var)
|
||||
|
@ -6827,13 +6824,8 @@ CheckModule(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList,
|
|||
|
||||
m.startFunctionBodies();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!CheckFunctionsParallel(m))
|
||||
return false;
|
||||
#else
|
||||
if (!CheckFunctionsSequential(m))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
m.finishFunctionBodies();
|
||||
|
||||
|
@ -6893,10 +6885,8 @@ EstablishPreconditions(ExclusiveContext *cx, AsmJSParser &parser)
|
|||
if (parser.pc->isArrowFunction())
|
||||
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by arrow function context");
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (ParallelCompilationEnabled(cx))
|
||||
EnsureHelperThreadsInitialized(cx);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -774,7 +774,6 @@ AsmJSMachExceptionHandler::AsmJSMachExceptionHandler()
|
|||
void
|
||||
AsmJSMachExceptionHandler::uninstall()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (installed_) {
|
||||
thread_port_t thread = mach_thread_self();
|
||||
kern_return_t kret = thread_set_exception_ports(thread,
|
||||
|
@ -812,15 +811,11 @@ AsmJSMachExceptionHandler::uninstall()
|
|||
JS_ASSERT(kret == KERN_SUCCESS);
|
||||
port_ = MACH_PORT_NULL;
|
||||
}
|
||||
#else
|
||||
JS_ASSERT(!installed_);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
AsmJSMachExceptionHandler::install(JSRuntime *rt)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!installed());
|
||||
kern_return_t kret;
|
||||
mach_port_t thread;
|
||||
|
@ -860,9 +855,6 @@ AsmJSMachExceptionHandler::install(JSRuntime *rt)
|
|||
error:
|
||||
uninstall();
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // If not Windows or Mac, assume Unix
|
||||
|
|
|
@ -78,13 +78,11 @@ CompileRuntime::addressOfInterrupt()
|
|||
return &runtime()->interrupt;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
const void *
|
||||
CompileRuntime::addressOfInterruptPar()
|
||||
{
|
||||
return &runtime()->interruptPar;
|
||||
}
|
||||
#endif
|
||||
|
||||
const void *
|
||||
CompileRuntime::addressOfThreadPool()
|
||||
|
|
|
@ -53,10 +53,7 @@ class CompileRuntime
|
|||
#endif
|
||||
|
||||
const void *addressOfInterrupt();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
const void *addressOfInterruptPar();
|
||||
#endif
|
||||
|
||||
const void *addressOfThreadPool();
|
||||
|
||||
|
|
|
@ -231,12 +231,10 @@ JitRuntime::initialize(JSContext *cx)
|
|||
if (!bailoutHandler_)
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
IonSpew(IonSpew_Codegen, "# Emitting parallel bailout handler");
|
||||
parallelBailoutHandler_ = generateBailoutHandler(cx, ParallelExecution);
|
||||
if (!parallelBailoutHandler_)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
IonSpew(IonSpew_Codegen, "# Emitting invalidator");
|
||||
invalidator_ = generateInvalidator(cx);
|
||||
|
@ -249,12 +247,10 @@ JitRuntime::initialize(JSContext *cx)
|
|||
if (!argumentsRectifier_)
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
IonSpew(IonSpew_Codegen, "# Emitting parallel arguments rectifier");
|
||||
parallelArgumentsRectifier_ = generateArgumentsRectifier(cx, ParallelExecution, nullptr);
|
||||
if (!parallelArgumentsRectifier_)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
IonSpew(IonSpew_Codegen, "# Emitting EnterJIT sequence");
|
||||
enterJIT_ = generateEnterJIT(cx, EnterJitOptimized);
|
||||
|
@ -365,13 +361,11 @@ JitRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress)
|
|||
if (!rt->signalHandlersInstalled() || !ionAlloc_ || !ionAlloc_->codeContains((char *) faultingAddress))
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// All places where the interrupt lock is taken must either ensure that Ion
|
||||
// code memory won't be accessed within, or call ensureIonCodeAccessible to
|
||||
// render the memory safe for accessing. Otherwise taking the lock below
|
||||
// will deadlock the process.
|
||||
JS_ASSERT(!rt->currentThreadOwnsInterruptLock());
|
||||
#endif
|
||||
|
||||
// Taking this lock is necessary to prevent the interrupting thread from marking
|
||||
// the memory as inaccessible while we are patching backedges. This will cause us
|
||||
|
@ -509,13 +503,11 @@ JitCompartment::ensureIonStubsExist(JSContext *cx)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!parallelStringConcatStub_) {
|
||||
parallelStringConcatStub_ = generateStringConcatStub(cx, ParallelExecution);
|
||||
if (!parallelStringConcatStub_)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -577,7 +569,6 @@ jit::FinishOffThreadBuilder(IonBuilder *builder)
|
|||
static inline void
|
||||
FinishAllOffThreadCompilations(JSCompartment *comp)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
AutoLockHelperThreadState lock;
|
||||
GlobalHelperThreadState::IonBuilderVector &finished = HelperThreadState().ionFinishedList();
|
||||
|
||||
|
@ -588,7 +579,6 @@ FinishAllOffThreadCompilations(JSCompartment *comp)
|
|||
HelperThreadState().remove(finished, &i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -1729,7 +1719,6 @@ CompileBackEnd(MIRGenerator *mir)
|
|||
void
|
||||
AttachFinishedCompilations(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JitCompartment *ion = cx->compartment()->jitCompartment();
|
||||
if (!ion)
|
||||
return;
|
||||
|
@ -1788,7 +1777,6 @@ AttachFinishedCompilations(JSContext *cx)
|
|||
|
||||
FinishOffThreadBuilder(builder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
|
||||
|
@ -1796,7 +1784,6 @@ static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
|
|||
static inline bool
|
||||
OffThreadCompilationAvailable(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
// Even if off thread compilation is enabled, compilation must still occur
|
||||
// on the main thread in some cases.
|
||||
//
|
||||
|
@ -1805,9 +1792,6 @@ OffThreadCompilationAvailable(JSContext *cx)
|
|||
return cx->runtime()->canUseOffthreadIonCompilation()
|
||||
&& HelperThreadState().cpuCount > 1
|
||||
&& CanUseExtraThreads();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -974,12 +974,8 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output)
|
|||
void
|
||||
MacroAssembler::checkInterruptFlagPar(Register tempReg, Label *fail)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
movePtr(ImmPtr(GetIonContext()->runtime->addressOfInterruptPar()), tempReg);
|
||||
branch32(Assembler::NonZero, Address(tempReg, 0), Imm32(0), fail);
|
||||
#else
|
||||
MOZ_ASSUME_UNREACHABLE("JSRuntime::interruptPar doesn't exist on non-threadsafe builds.");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Save an exit frame (which must be aligned to the stack pointer) to
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
# include "jit/MIRGraph.h"
|
||||
#endif
|
||||
|
||||
#include "jslock.h"
|
||||
|
||||
// perf expects its data to be in a file /tmp/perf-PID.map, but for Android
|
||||
// and B2G the map files are written to /data/local/tmp/perf-PID.map
|
||||
//
|
||||
|
@ -48,10 +50,7 @@ static bool PerfChecked = false;
|
|||
|
||||
static FILE *PerfFilePtr = nullptr;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
# include "jslock.h"
|
||||
static PRLock *PerfMutex;
|
||||
#endif
|
||||
|
||||
static bool
|
||||
openPerfMap(const char *dir)
|
||||
|
@ -95,11 +94,9 @@ js::jit::CheckPerf() {
|
|||
}
|
||||
|
||||
if (PerfMode != PERF_MODE_NONE) {
|
||||
#ifdef JS_THREADSAFE
|
||||
PerfMutex = PR_NewLock();
|
||||
if (!PerfMutex)
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
|
||||
if (openPerfMap(PERF_SPEW_DIR)) {
|
||||
PerfChecked = true;
|
||||
|
@ -137,9 +134,7 @@ lockPerfMap(void)
|
|||
if (!PerfEnabled())
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(PerfMutex);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(PerfFilePtr);
|
||||
return true;
|
||||
|
@ -150,9 +145,7 @@ unlockPerfMap()
|
|||
{
|
||||
JS_ASSERT(PerfFilePtr);
|
||||
fflush(PerfFilePtr);
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Unlock(PerfMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t PerfSpewer::nextFunctionIndex = 0;
|
||||
|
|
|
@ -385,31 +385,23 @@ class SimulatorRuntime
|
|||
{}
|
||||
~SimulatorRuntime();
|
||||
bool init() {
|
||||
#ifdef JS_THREADSAFE
|
||||
lock_ = PR_NewLock();
|
||||
if (!lock_)
|
||||
return false;
|
||||
#endif
|
||||
if (!icache_.init())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
ICacheMap &icache() {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
return icache_;
|
||||
}
|
||||
Redirection *redirection() const {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
return redirection_;
|
||||
}
|
||||
void setRedirection(js::jit::Redirection *redirection) {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
redirection_ = redirection;
|
||||
}
|
||||
};
|
||||
|
@ -423,21 +415,17 @@ class AutoLockSimulatorRuntime
|
|||
AutoLockSimulatorRuntime(SimulatorRuntime *srt)
|
||||
: srt_(srt)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(srt_->lock_);
|
||||
MOZ_ASSERT(!srt_->lockOwner_);
|
||||
#ifdef DEBUG
|
||||
srt_->lockOwner_ = PR_GetCurrentThread();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
~AutoLockSimulatorRuntime() {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(srt_->lockOwner_ == PR_GetCurrentThread());
|
||||
srt_->lockOwner_ = nullptr;
|
||||
PR_Unlock(srt_->lock_);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1264,10 +1252,8 @@ SimulatorRuntime::~SimulatorRuntime()
|
|||
js_delete(r);
|
||||
r = next;
|
||||
}
|
||||
#ifdef JS_THREADSAFE
|
||||
if (lock_)
|
||||
PR_DestroyLock(lock_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Sets the register in the architecture state. It will also deal with updating
|
||||
|
|
|
@ -519,31 +519,23 @@ class SimulatorRuntime
|
|||
lockOwner_(nullptr) {}
|
||||
~SimulatorRuntime();
|
||||
bool init() {
|
||||
#ifdef JS_THREADSAFE
|
||||
lock_ = PR_NewLock();
|
||||
if (!lock_)
|
||||
return false;
|
||||
#endif
|
||||
if (!icache_.init())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
ICacheMap &icache() {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
return icache_;
|
||||
}
|
||||
Redirection *redirection() const {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
return redirection_;
|
||||
}
|
||||
void setRedirection(js::jit::Redirection *redirection) {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
|
||||
#endif
|
||||
redirection_ = redirection;
|
||||
}
|
||||
};
|
||||
|
@ -556,21 +548,17 @@ class AutoLockSimulatorRuntime
|
|||
public:
|
||||
AutoLockSimulatorRuntime(SimulatorRuntime *srt)
|
||||
: srt_(srt) {
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(srt_->lock_);
|
||||
MOZ_ASSERT(!srt_->lockOwner_);
|
||||
#ifdef DEBUG
|
||||
srt_->lockOwner_ = PR_GetCurrentThread();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
~AutoLockSimulatorRuntime() {
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(srt_->lockOwner_ == PR_GetCurrentThread());
|
||||
srt_->lockOwner_ = nullptr;
|
||||
PR_Unlock(srt_->lock_);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1415,10 +1403,8 @@ SimulatorRuntime::~SimulatorRuntime()
|
|||
js_delete(r);
|
||||
r = next;
|
||||
}
|
||||
#ifdef JS_THREADSAFE
|
||||
if (lock_)
|
||||
PR_DestroyLock(lock_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get the active Simulator for the current thread.
|
||||
|
|
|
@ -2071,7 +2071,6 @@ CodeGeneratorX86Shared::visitForkJoinGetSlice(LForkJoinGetSlice *ins)
|
|||
JitCode *
|
||||
JitRuntime::generateForkJoinGetSliceStub(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
// We need two fixed temps. We need to fix eax for cmpxchg, and edx for
|
||||
|
@ -2220,9 +2219,6 @@ JitRuntime::generateForkJoinGetSliceStub(JSContext *cx)
|
|||
#endif
|
||||
|
||||
return code;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
|
|
|
@ -618,9 +618,7 @@ JS_ShutDown(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
HelperThreadState().finish();
|
||||
#endif
|
||||
|
||||
PRMJ_NowShutdown();
|
||||
|
||||
|
@ -699,7 +697,6 @@ JS_SetRuntimePrivate(JSRuntime *rt, void *data)
|
|||
rt->data = data;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
static void
|
||||
StartRequest(JSContext *cx)
|
||||
{
|
||||
|
@ -730,36 +727,27 @@ StopRequest(JSContext *cx)
|
|||
rt->triggerActivityCallback(false);
|
||||
}
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_BeginRequest(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
cx->outstandingRequests++;
|
||||
StartRequest(cx);
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_EndRequest(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(cx->outstandingRequests != 0);
|
||||
cx->outstandingRequests--;
|
||||
StopRequest(cx);
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_IsInRequest(JSRuntime *rt)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
return rt->requestDepth != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
@ -4566,13 +4554,11 @@ JS::CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, si
|
|||
if (length < TINY_LENGTH)
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// If the parsing task would have to wait for GC to complete, it'll probably
|
||||
// be faster to just start it synchronously on the main thread unless the
|
||||
// script is huge.
|
||||
if (OffThreadParsingMustWaitForGC(cx->runtime()) && length < HUGE_LENGTH)
|
||||
return false;
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
return cx->runtime()->canUseParallelParsing() && CanUseExtraThreads();
|
||||
|
@ -4590,7 +4576,6 @@ JS::CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
|
|||
JS_PUBLIC_API(JSScript *)
|
||||
JS::FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
|
||||
if (maybecx) {
|
||||
|
@ -4603,9 +4588,6 @@ JS::FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token)
|
|||
} else {
|
||||
return HelperThreadState().finishParseTask(maybecx, rt, token);
|
||||
}
|
||||
#else
|
||||
MOZ_CRASH("Off thread compilation is not available.");
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -6228,11 +6210,7 @@ JS_IsStopIteration(jsval v)
|
|||
JS_PUBLIC_API(intptr_t)
|
||||
JS_GetCurrentThread()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return reinterpret_cast<intptr_t>(PR_GetCurrentThread());
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern MOZ_NEVER_INLINE JS_PUBLIC_API(void)
|
||||
|
@ -6497,28 +6475,17 @@ UnhideScriptedCaller(JSContext *cx)
|
|||
|
||||
} /* namespace JS */
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
static PRStatus
|
||||
CallOnce(void *func)
|
||||
{
|
||||
JSInitCallback init = JS_DATA_TO_FUNC_PTR(JSInitCallback, func);
|
||||
return init() ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_CallOnce(JSCallOnceType *once, JSInitCallback func)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return PR_CallOnceWithArg(once, CallOnce, JS_FUNC_TO_DATA_PTR(void *, func)) == PR_SUCCESS;
|
||||
#else
|
||||
if (!*once) {
|
||||
*once = true;
|
||||
return func();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag)
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace JS {
|
|||
class Latin1CharsZ;
|
||||
class TwoByteChars;
|
||||
|
||||
#if defined JS_THREADSAFE && defined JS_DEBUG
|
||||
#ifdef JS_DEBUG
|
||||
|
||||
class JS_PUBLIC_API(AutoCheckRequestDepth)
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ class JS_PUBLIC_API(AutoCheckRequestDepth)
|
|||
# define CHECK_REQUEST(cx) \
|
||||
((void) 0)
|
||||
|
||||
#endif /* JS_THREADSAFE && JS_DEBUG */
|
||||
#endif /* JS_DEBUG */
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
/*
|
||||
|
@ -1344,7 +1344,7 @@ class JSAutoCheckRequest
|
|||
explicit JSAutoCheckRequest(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
#if defined JS_THREADSAFE && defined JS_DEBUG
|
||||
#ifdef JS_DEBUG
|
||||
mContext = cx;
|
||||
JS_ASSERT(JS_IsInRequest(JS_GetRuntime(cx)));
|
||||
#endif
|
||||
|
@ -1352,14 +1352,14 @@ class JSAutoCheckRequest
|
|||
}
|
||||
|
||||
~JSAutoCheckRequest() {
|
||||
#if defined JS_THREADSAFE && defined JS_DEBUG
|
||||
#ifdef JS_DEBUG
|
||||
JS_ASSERT(JS_IsInRequest(JS_GetRuntime(mContext)));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
#if defined JS_THREADSAFE && defined JS_DEBUG
|
||||
#ifdef JS_DEBUG
|
||||
JSContext *mContext;
|
||||
#endif
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
|
|
@ -191,9 +191,7 @@ js::NewContext(JSRuntime *rt, size_t stackChunkSize)
|
|||
* of the struct.
|
||||
*/
|
||||
if (!rt->haveCreatedContext) {
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_BeginRequest(cx);
|
||||
#endif
|
||||
bool ok = rt->initializeAtoms(cx);
|
||||
if (ok)
|
||||
ok = rt->initSelfHosting(cx);
|
||||
|
@ -201,9 +199,8 @@ js::NewContext(JSRuntime *rt, size_t stackChunkSize)
|
|||
if (ok && !rt->parentRuntime)
|
||||
ok = rt->transformToPermanentAtoms();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_EndRequest(cx);
|
||||
#endif
|
||||
|
||||
if (!ok) {
|
||||
DestroyContext(cx, DCM_NEW_FAILED);
|
||||
return nullptr;
|
||||
|
@ -227,10 +224,8 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
|
|||
JSRuntime *rt = cx->runtime();
|
||||
JS_AbortIfWrongThread(rt);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (cx->outstandingRequests != 0)
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
|
||||
cx->checkNoGCRooters();
|
||||
|
||||
|
@ -979,7 +974,7 @@ js_GetErrorMessage(void *userRef, const unsigned errorNumber)
|
|||
bool
|
||||
js::InvokeInterruptCallback(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT_REQUEST_DEPTH(cx);
|
||||
JS_ASSERT(cx->runtime()->requestDepth >= 1);
|
||||
|
||||
JSRuntime *rt = cx->runtime();
|
||||
JS_ASSERT(rt->interrupt);
|
||||
|
@ -996,9 +991,7 @@ js::InvokeInterruptCallback(JSContext *cx)
|
|||
js::gc::GCIfNeeded(cx);
|
||||
|
||||
#ifdef JS_ION
|
||||
#ifdef JS_THREADSAFE
|
||||
rt->interruptPar = false;
|
||||
#endif
|
||||
|
||||
// A worker thread may have requested an interrupt after finishing an Ion
|
||||
// compilation.
|
||||
|
@ -1114,9 +1107,7 @@ JSContext::JSContext(JSRuntime *rt)
|
|||
errorReporter(nullptr),
|
||||
data(nullptr),
|
||||
data2(nullptr),
|
||||
#ifdef JS_THREADSAFE
|
||||
outstandingRequests(0),
|
||||
#endif
|
||||
iterValue(MagicValue(JS_NO_ITER_VALUE)),
|
||||
jitIsBroken(false),
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
|
@ -1345,7 +1336,7 @@ JSContext::findVersion() const
|
|||
return runtime()->defaultVersion();
|
||||
}
|
||||
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
#ifdef DEBUG
|
||||
|
||||
JS::AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
|
||||
: cx(cx)
|
||||
|
|
|
@ -488,11 +488,9 @@ struct JSContext : public js::ExclusiveContext,
|
|||
|
||||
js::LifoAlloc &tempLifoAlloc() { return runtime()->tempLifoAlloc; }
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
unsigned outstandingRequests;/* number of JS_BeginRequest calls
|
||||
without the corresponding
|
||||
JS_EndRequest. */
|
||||
#endif
|
||||
|
||||
/* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
|
||||
js::Value iterValue;
|
||||
|
@ -785,12 +783,6 @@ js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumb
|
|||
|
||||
extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
# define JS_ASSERT_REQUEST_DEPTH(cx) JS_ASSERT((cx)->runtime()->requestDepth >= 1)
|
||||
#else
|
||||
# define JS_ASSERT_REQUEST_DEPTH(cx) ((void) 0)
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
|
@ -818,7 +810,7 @@ HandleExecutionInterrupt(JSContext *cx);
|
|||
inline bool
|
||||
CheckForInterrupt(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT_REQUEST_DEPTH(cx);
|
||||
MOZ_ASSERT(cx->runtime()->requestDepth >= 1);
|
||||
return !cx->runtime()->interrupt || InvokeInterruptCallback(cx);
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1020,6 @@ bool intrinsic_TypeDescrIsSizedArrayType(JSContext *cx, unsigned argc, Value *vp
|
|||
|
||||
class AutoLockForExclusiveAccess
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JSRuntime *runtime;
|
||||
|
||||
void init(JSRuntime *rt) {
|
||||
|
@ -1064,19 +1055,6 @@ class AutoLockForExclusiveAccess
|
|||
runtime->mainThreadHasExclusiveAccess = false;
|
||||
}
|
||||
}
|
||||
#else // JS_THREADSAFE
|
||||
public:
|
||||
AutoLockForExclusiveAccess(ExclusiveContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
AutoLockForExclusiveAccess(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
~AutoLockForExclusiveAccess() {
|
||||
// An empty destructor is needed to avoid warnings from clang about
|
||||
// unused local variables of this type.
|
||||
}
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
|
|
@ -834,13 +834,11 @@ js::GetContextStructuredCloneCallbacks(JSContext *cx)
|
|||
return cx->runtime()->structuredCloneCallbacks;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FRIEND_API(bool)
|
||||
js::ContextHasOutstandingRequests(const JSContext *cx)
|
||||
{
|
||||
return cx->outstandingRequests > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg)
|
||||
|
@ -1209,11 +1207,7 @@ js::ReportErrorWithId(JSContext *cx, const char *msg, HandleId id)
|
|||
JS_PUBLIC_API(bool)
|
||||
js::IsInRequest(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return !!cx->runtime()->requestDepth;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1055,10 +1055,8 @@ GetPCCountScriptSummary(JSContext *cx, size_t script);
|
|||
JS_FRIEND_API(JSString *)
|
||||
GetPCCountScriptContents(JSContext *cx, size_t script);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FRIEND_API(bool)
|
||||
ContextHasOutstandingRequests(const JSContext *cx);
|
||||
#endif
|
||||
|
||||
typedef void
|
||||
(* ActivityCallback)(void *arg, bool active);
|
||||
|
|
|
@ -1281,11 +1281,9 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
|
|||
{
|
||||
InitMemorySubsystem();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
lock = PR_NewLock();
|
||||
if (!lock)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!chunkSet.init(INITIAL_CHUNK_CAPACITY))
|
||||
return false;
|
||||
|
@ -1338,11 +1336,9 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
|
|||
void
|
||||
GCRuntime::recordNativeStackTop()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
/* Record the stack top here only if we are called from a request. */
|
||||
if (!rt->requestDepth)
|
||||
return;
|
||||
#endif
|
||||
conservativeGC.recordStackTop();
|
||||
}
|
||||
|
||||
|
@ -1386,12 +1382,10 @@ GCRuntime::finish()
|
|||
|
||||
FinishPersistentRootedChains(rt);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (lock) {
|
||||
PR_DestroyLock(lock);
|
||||
lock = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
FinishTrace();
|
||||
}
|
||||
|
@ -1860,7 +1854,6 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind,
|
|||
AutoLockGC maybeLock;
|
||||
|
||||
bool backgroundFinalizationIsRunning = false;
|
||||
#ifdef JS_THREADSAFE
|
||||
ArenaLists::BackgroundFinalizeState *bfs = &backgroundFinalizeState[thingKind];
|
||||
if (*bfs != BFS_DONE) {
|
||||
/*
|
||||
|
@ -1879,7 +1872,6 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind,
|
|||
JS_ASSERT(*bfs == BFS_DONE);
|
||||
}
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
ArenaHeader *aheader;
|
||||
ArenaList *al = &arenaLists[thingKind];
|
||||
|
@ -2026,10 +2018,7 @@ inline void
|
|||
ArenaLists::queueForBackgroundSweep(FreeOp *fop, AllocKind thingKind)
|
||||
{
|
||||
JS_ASSERT(IsBackgroundFinalized(thingKind));
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!fop->runtime()->gc.isBackgroundSweeping());
|
||||
#endif
|
||||
|
||||
ArenaList *al = &arenaLists[thingKind];
|
||||
if (al->isEmpty()) {
|
||||
|
@ -2200,10 +2189,8 @@ ArenaLists::refillFreeList(ThreadSafeContext *cx, AllocKind thingKind)
|
|||
cx->asJSContext()->runtime()->gc.incrementalState != NO_INCREMENTAL &&
|
||||
zone->usage.gcBytes() > zone->gcTriggerBytes;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT_IF(cx->isJSContext() && allowGC,
|
||||
!cx->asJSContext()->runtime()->currentThreadHasExclusiveAccess());
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (MOZ_UNLIKELY(runGC)) {
|
||||
|
@ -2233,7 +2220,6 @@ ArenaLists::refillFreeList(ThreadSafeContext *cx, AllocKind thingKind)
|
|||
cx->asJSContext()->runtime()->gc.waitBackgroundSweepEnd();
|
||||
}
|
||||
} else {
|
||||
#ifdef JS_THREADSAFE
|
||||
/*
|
||||
* If we're off the main thread, we try to allocate once and
|
||||
* return whatever value we get. If we aren't in a ForkJoin
|
||||
|
@ -2253,9 +2239,6 @@ ArenaLists::refillFreeList(ThreadSafeContext *cx, AllocKind thingKind)
|
|||
maybeStartBackgroundAllocation);
|
||||
if (thing)
|
||||
return thing;
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!cx->allowGC() || !allowGC)
|
||||
|
@ -2640,7 +2623,7 @@ GCRuntime::sweepBackgroundThings(bool onBackgroundThread)
|
|||
void
|
||||
GCRuntime::assertBackgroundSweepingFinished()
|
||||
{
|
||||
#if defined(JS_THREADSAFE) && defined(DEBUG)
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!sweepingZones);
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
for (unsigned i = 0; i < FINALIZE_LIMIT; ++i) {
|
||||
|
@ -2651,7 +2634,6 @@ GCRuntime::assertBackgroundSweepingFinished()
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
unsigned
|
||||
js::GetCPUCount()
|
||||
{
|
||||
|
@ -2668,12 +2650,10 @@ js::GetCPUCount()
|
|||
}
|
||||
return ncpus;
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
bool
|
||||
GCHelperState::init()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!(done = PR_NewCondVar(rt->gc.lock)))
|
||||
return false;
|
||||
|
||||
|
@ -2683,9 +2663,6 @@ GCHelperState::init()
|
|||
} else {
|
||||
backgroundAllocation = false;
|
||||
}
|
||||
#else
|
||||
backgroundAllocation = false;
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2698,15 +2675,11 @@ GCHelperState::finish()
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// Wait for any lingering background sweeping to finish.
|
||||
waitBackgroundSweepEnd();
|
||||
|
||||
if (done)
|
||||
PR_DestroyCondVar(done);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
GCHelperState::State
|
||||
|
@ -2726,22 +2699,17 @@ GCHelperState::setState(State state)
|
|||
void
|
||||
GCHelperState::startBackgroundThread(State newState)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!thread && state() == IDLE && newState != IDLE);
|
||||
setState(newState);
|
||||
|
||||
if (!HelperThreadState().gcHelperWorklist().append(this))
|
||||
CrashAtUnhandlableOOM("Could not add to pending GC helpers list");
|
||||
HelperThreadState().notifyAll(GlobalHelperThreadState::PRODUCER);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GCHelperState::waitForBackgroundThread()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
|
||||
rt->gc.lockOwner = nullptr;
|
||||
|
@ -2749,15 +2717,11 @@ GCHelperState::waitForBackgroundThread()
|
|||
#ifdef DEBUG
|
||||
rt->gc.lockOwner = PR_GetCurrentThread();
|
||||
#endif
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GCHelperState::work()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CanUseExtraThreads());
|
||||
|
||||
AutoLockGC lock(rt);
|
||||
|
@ -2808,15 +2772,11 @@ GCHelperState::work()
|
|||
thread = nullptr;
|
||||
|
||||
PR_NotifyAllCondVar(done);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GCHelperState::startBackgroundSweep(bool shouldShrink)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CanUseExtraThreads());
|
||||
|
||||
AutoLockHelperThreadState helperLock;
|
||||
|
@ -2826,14 +2786,12 @@ GCHelperState::startBackgroundSweep(bool shouldShrink)
|
|||
sweepFlag = true;
|
||||
shrinkFlag = shouldShrink;
|
||||
startBackgroundThread(SWEEPING);
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
/* Must be called with the GC lock taken. */
|
||||
void
|
||||
GCHelperState::startBackgroundShrink()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(CanUseExtraThreads());
|
||||
switch (state()) {
|
||||
case IDLE:
|
||||
|
@ -2852,25 +2810,21 @@ GCHelperState::startBackgroundShrink()
|
|||
*/
|
||||
break;
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
void
|
||||
GCHelperState::waitBackgroundSweepEnd()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
AutoLockGC lock(rt);
|
||||
while (state() == SWEEPING)
|
||||
waitForBackgroundThread();
|
||||
if (rt->gc.incrementalState == NO_INCREMENTAL)
|
||||
rt->gc.assertBackgroundSweepingFinished();
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
void
|
||||
GCHelperState::waitBackgroundSweepOrAllocEnd()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
AutoLockGC lock(rt);
|
||||
if (state() == ALLOCATING)
|
||||
setState(CANCEL_ALLOCATION);
|
||||
|
@ -2878,17 +2832,14 @@ GCHelperState::waitBackgroundSweepOrAllocEnd()
|
|||
waitForBackgroundThread();
|
||||
if (rt->gc.incrementalState == NO_INCREMENTAL)
|
||||
rt->gc.assertBackgroundSweepingFinished();
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
/* Must be called with the GC lock taken. */
|
||||
inline void
|
||||
GCHelperState::startBackgroundAllocationIfIdle()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (state_ == IDLE)
|
||||
startBackgroundThread(ALLOCATING);
|
||||
#endif /* JS_THREADSAFE */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2910,7 +2861,6 @@ GCHelperState::replenishAndFreeLater(void *ptr)
|
|||
js_free(ptr);
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
/* Must be called with the GC lock taken. */
|
||||
void
|
||||
GCHelperState::doSweep()
|
||||
|
@ -2950,16 +2900,11 @@ GCHelperState::doSweep()
|
|||
rt->gc.expireChunksAndArenas(true);
|
||||
}
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
bool
|
||||
GCHelperState::onBackgroundThread()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return PR_GetCurrentThread() == thread;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -4340,9 +4285,7 @@ GCRuntime::beginSweepPhase(bool lastGC)
|
|||
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
sweepOnBackgroundThread = !lastGC && !TraceEnabled() && CanUseExtraThreads();
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
|
||||
|
@ -4631,12 +4574,8 @@ AutoTraceSession::AutoTraceSession(JSRuntime *rt, js::HeapState heapState)
|
|||
if (rt->exclusiveThreadsPresent()) {
|
||||
// Lock the helper thread state when changing the heap state in the
|
||||
// presence of exclusive threads, to avoid racing with refillFreeList.
|
||||
#ifdef JS_THREADSAFE
|
||||
AutoLockHelperThreadState lock;
|
||||
rt->gc.heapState = heapState;
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
} else {
|
||||
rt->gc.heapState = heapState;
|
||||
}
|
||||
|
@ -4647,15 +4586,11 @@ AutoTraceSession::~AutoTraceSession()
|
|||
JS_ASSERT(runtime->isHeapBusy());
|
||||
|
||||
if (runtime->exclusiveThreadsPresent()) {
|
||||
#ifdef JS_THREADSAFE
|
||||
AutoLockHelperThreadState lock;
|
||||
runtime->gc.heapState = prevState;
|
||||
|
||||
// Notify any helper threads waiting for the trace session to end.
|
||||
HelperThreadState().notifyAll(GlobalHelperThreadState::PRODUCER);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
} else {
|
||||
runtime->gc.heapState = prevState;
|
||||
}
|
||||
|
@ -5198,10 +5133,8 @@ GCRuntime::collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
|||
/* If we attempt to invoke the GC while we are running in the GC, assert. */
|
||||
MOZ_ASSERT(!rt->isHeapBusy());
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
/* The engine never locks across anything that could GC. */
|
||||
MOZ_ASSERT(!rt->currentThreadHasExclusiveAccess());
|
||||
#endif
|
||||
|
||||
if (rt->mainThread.suppressGC)
|
||||
return;
|
||||
|
@ -5259,11 +5192,8 @@ GCRuntime::collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
|||
repeat = (poked && cleanUpEverything) || wasReset;
|
||||
} while (repeat);
|
||||
|
||||
if (incrementalState == NO_INCREMENTAL) {
|
||||
#ifdef JS_THREADSAFE
|
||||
if (incrementalState == NO_INCREMENTAL)
|
||||
EnqueuePendingParseTasksAfterGC(rt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5371,11 +5301,7 @@ GCRuntime::shrinkBuffers()
|
|||
AutoLockGC lock(rt);
|
||||
JS_ASSERT(!rt->isHeapBusy());
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
helperState.startBackgroundShrink();
|
||||
#else
|
||||
expireChunksAndArenas(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5786,13 +5712,12 @@ ArenaLists::adoptArenas(JSRuntime *rt, ArenaLists *fromArenaLists)
|
|||
fromArenaLists->purge();
|
||||
|
||||
for (size_t thingKind = 0; thingKind != FINALIZE_LIMIT; thingKind++) {
|
||||
#ifdef JS_THREADSAFE
|
||||
// When we enter a parallel section, we join the background
|
||||
// thread, and we do not run GC while in the parallel section,
|
||||
// so no finalizer should be active!
|
||||
normalizeBackgroundFinalizeState(AllocKind(thingKind));
|
||||
fromArenaLists->normalizeBackgroundFinalizeState(AllocKind(thingKind));
|
||||
#endif
|
||||
|
||||
ArenaList *fromList = &fromArenaLists->arenaLists[thingKind];
|
||||
ArenaList *toList = &arenaLists[thingKind];
|
||||
fromList->check();
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef jslock_h
|
||||
#define jslock_h
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
#ifdef JS_POSIX_NSPR
|
||||
|
||||
#include "vm/PosixNSPR.h"
|
||||
|
@ -22,12 +20,4 @@
|
|||
|
||||
#endif
|
||||
|
||||
#else /* JS_THREADSAFE */
|
||||
|
||||
typedef struct PRThread PRThread;
|
||||
typedef struct PRCondVar PRCondVar;
|
||||
typedef struct PRLock PRLock;
|
||||
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
#endif /* jslock_h */
|
||||
|
|
|
@ -144,11 +144,7 @@ class JS_PUBLIC_API(JSTracer);
|
|||
|
||||
class JSFlatString;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
typedef struct PRCallOnceType JSCallOnceType;
|
||||
#else
|
||||
typedef bool JSCallOnceType;
|
||||
#endif
|
||||
typedef bool (*JSInitCallback)(void);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1649,14 +1649,10 @@ ScriptSource::setSourceCopy(ExclusiveContext *cx, SourceBufferHolder &srcBuf,
|
|||
// thread (see HelperThreadState::canStartParseTask) which would cause a
|
||||
// deadlock if there wasn't a second helper thread that could make
|
||||
// progress on our compression task.
|
||||
#if defined(JS_THREADSAFE)
|
||||
bool canCompressOffThread =
|
||||
HelperThreadState().cpuCount > 1 &&
|
||||
HelperThreadState().threadCount >= 2 &&
|
||||
CanUseExtraThreads();
|
||||
#else
|
||||
bool canCompressOffThread = false;
|
||||
#endif
|
||||
const size_t TINY_SCRIPT = 256;
|
||||
const size_t HUGE_SCRIPT = 5 * 1024 * 1024;
|
||||
if (TINY_SCRIPT <= srcBuf.length() && srcBuf.length() < HUGE_SCRIPT && canCompressOffThread) {
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "jsatom.h"
|
||||
#ifdef JS_THREADSAFE
|
||||
#include "jslock.h"
|
||||
#endif
|
||||
#include "jsobj.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jstypes.h"
|
||||
|
|
|
@ -33,9 +33,7 @@
|
|||
#include <stdlib.h> /* for _set_invalid_parameter_handler */
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#include "prinit.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -91,9 +89,7 @@ struct CalibrationData {
|
|||
|
||||
bool calibrated;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
CRITICAL_SECTION data_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
static CalibrationData calibration = { 0 };
|
||||
|
@ -140,9 +136,7 @@ PRMJ_NowInit()
|
|||
calibration.freq = double(liFreq.QuadPart);
|
||||
MOZ_ASSERT(calibration.freq > 0.0);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
InitializeCriticalSectionAndSpinCount(&calibration.data_lock, DataLockSpinCount);
|
||||
#endif
|
||||
|
||||
// Windows 8 has a new API function we can use.
|
||||
if (HMODULE h = GetModuleHandle("kernel32.dll")) {
|
||||
|
@ -151,7 +145,6 @@ PRMJ_NowInit()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void
|
||||
PRMJ_NowShutdown()
|
||||
{
|
||||
|
@ -162,14 +155,6 @@ PRMJ_NowShutdown()
|
|||
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
|
||||
#define MUTEX_SETSPINCOUNT(m, c) SetCriticalSectionSpinCount((m),(c))
|
||||
|
||||
#else
|
||||
|
||||
#define MUTEX_LOCK(m)
|
||||
#define MUTEX_UNLOCK(m)
|
||||
#define MUTEX_SETSPINCOUNT(m, c)
|
||||
|
||||
#endif
|
||||
|
||||
// Please see bug 363258 for why the win32 timing code is so complex.
|
||||
int64_t
|
||||
PRMJ_Now()
|
||||
|
|
|
@ -44,7 +44,7 @@ PRMJ_NowInit() {}
|
|||
#endif
|
||||
|
||||
/* Release the resources associated with PRMJ_Now; don't call PRMJ_Now again */
|
||||
#if defined(JS_THREADSAFE) && defined(XP_WIN)
|
||||
#ifdef XP_WIN
|
||||
extern void
|
||||
PRMJ_NowShutdown();
|
||||
#else
|
||||
|
|
|
@ -40,9 +40,7 @@
|
|||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsfun.h"
|
||||
#ifdef JS_THREADSAFE
|
||||
#include "jslock.h"
|
||||
#endif
|
||||
#include "jsobj.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsscript.h"
|
||||
|
@ -149,8 +147,6 @@ CancelExecution(JSRuntime *rt);
|
|||
/*
|
||||
* Watchdog thread state.
|
||||
*/
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
static PRLock *gWatchdogLock = nullptr;
|
||||
static PRCondVar *gWatchdogWakeup = nullptr;
|
||||
static PRThread *gWatchdogThread = nullptr;
|
||||
|
@ -159,12 +155,6 @@ static int64_t gWatchdogTimeout = 0;
|
|||
|
||||
static PRCondVar *gSleepWakeup = nullptr;
|
||||
|
||||
#else
|
||||
|
||||
static JSRuntime *gRuntime = nullptr;
|
||||
|
||||
#endif
|
||||
|
||||
static int gExitCode = 0;
|
||||
static bool gQuitting = false;
|
||||
static bool gGotError = false;
|
||||
|
@ -2795,7 +2785,6 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return ok;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
struct WorkerInput
|
||||
{
|
||||
JSRuntime *runtime;
|
||||
|
@ -2894,7 +2883,6 @@ EvalInWorker(JSContext *cx, unsigned argc, jsval *vp)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
ShapeOf(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
|
@ -3035,8 +3023,6 @@ Resolver(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
/*
|
||||
* Check that t1 comes strictly before t2. The function correctly deals with
|
||||
* wrap-around between t2 and t1 assuming that t2 and t1 stays within INT32_MAX
|
||||
|
@ -3204,74 +3190,6 @@ ScheduleWatchdog(JSRuntime *rt, double t)
|
|||
return true;
|
||||
}
|
||||
|
||||
#else /* !JS_THREADSAFE */
|
||||
|
||||
#ifdef XP_WIN
|
||||
static HANDLE gTimerHandle = 0;
|
||||
|
||||
VOID CALLBACK
|
||||
TimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
|
||||
{
|
||||
CancelExecution((JSRuntime *) lpParameter);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void
|
||||
AlarmHandler(int sig)
|
||||
{
|
||||
CancelExecution(gRuntime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool
|
||||
InitWatchdog(JSRuntime *rt)
|
||||
{
|
||||
gRuntime = rt;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
KillWatchdog()
|
||||
{
|
||||
ScheduleWatchdog(gRuntime, -1);
|
||||
}
|
||||
|
||||
static bool
|
||||
ScheduleWatchdog(JSRuntime *rt, double t)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
if (gTimerHandle) {
|
||||
DeleteTimerQueueTimer(nullptr, gTimerHandle, nullptr);
|
||||
gTimerHandle = 0;
|
||||
}
|
||||
if (t > 0 &&
|
||||
!CreateTimerQueueTimer(&gTimerHandle,
|
||||
nullptr,
|
||||
(WAITORTIMERCALLBACK)TimerCallback,
|
||||
rt,
|
||||
DWORD(ceil(t * 1000.0)),
|
||||
0,
|
||||
WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE)) {
|
||||
gTimerHandle = 0;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
/* FIXME: use setitimer when available for sub-second resolution. */
|
||||
if (t <= 0) {
|
||||
alarm(0);
|
||||
signal(SIGALRM, nullptr);
|
||||
} else {
|
||||
signal(SIGALRM, AlarmHandler); /* set the Alarm signal capture */
|
||||
alarm(ceil(t));
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* !JS_THREADSAFE */
|
||||
|
||||
static void
|
||||
CancelExecution(JSRuntime *rt)
|
||||
{
|
||||
|
@ -3280,14 +3198,7 @@ CancelExecution(JSRuntime *rt)
|
|||
|
||||
if (!gInterruptFunc.ref().get().isNull()) {
|
||||
static const char msg[] = "Script runs for too long, terminating.\n";
|
||||
#if defined(XP_UNIX) && !defined(JS_THREADSAFE)
|
||||
/* It is not safe to call fputs from signals. */
|
||||
/* Dummy assignment avoids GCC warning on "attribute warn_unused_result" */
|
||||
ssize_t dummy = write(2, msg, sizeof(msg) - 1);
|
||||
(void)dummy;
|
||||
#else
|
||||
fputs(msg, stderr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3588,8 +3499,6 @@ SyntaxParse(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
class OffThreadState {
|
||||
public:
|
||||
enum State {
|
||||
|
@ -3782,8 +3691,6 @@ runOffThreadScript(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return JS_ExecuteScript(cx, cx->global(), script, args.rval());
|
||||
}
|
||||
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
struct FreeOnReturn
|
||||
{
|
||||
JSContext *cx;
|
||||
|
@ -4707,11 +4614,9 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
" Evaluate 'str' in the nth up frame.\n"
|
||||
" If 'save' (default false), save the frame chain."),
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FN_HELP("evalInWorker", EvalInWorker, 1, 0,
|
||||
"evalInWorker(str)",
|
||||
" Evaluate 'str' in a separate thread with its own runtime.\n"),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("shapeOf", ShapeOf, 1, 0,
|
||||
"shapeOf(obj)",
|
||||
|
@ -4728,11 +4633,9 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
" Report statistics about arrays."),
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FN_HELP("sleep", Sleep_fn, 1, 0,
|
||||
"sleep(dt)",
|
||||
" Sleep for dt seconds."),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("snarf", Snarf, 1, 0,
|
||||
"snarf(filename, [\"binary\"])",
|
||||
|
@ -4760,7 +4663,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
"syntaxParse(code)",
|
||||
" Check the syntax of a string, returning success value"),
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FN_HELP("offThreadCompileScript", OffThreadCompileScript, 1, 0,
|
||||
"offThreadCompileScript(code[, options])",
|
||||
" Compile |code| on a helper thread. To wait for the compilation to finish\n"
|
||||
|
@ -4783,8 +4685,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
" throw the appropriate exception; otherwise, run the script and return\n"
|
||||
" its value."),
|
||||
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("timeout", Timeout, 1, 0,
|
||||
"timeout([seconds], [func])",
|
||||
" Get/Set the limit in seconds for the execution time for the current context.\n"
|
||||
|
@ -5742,31 +5642,10 @@ static JS::AsmJSCacheOps asmJSCacheOps = {
|
|||
ShellBuildId
|
||||
};
|
||||
|
||||
/*
|
||||
* Avoid a reentrancy hazard.
|
||||
*
|
||||
* The non-JS_THREADSAFE shell uses a signal handler to implement timeout().
|
||||
* The JS engine is not really reentrant, but JS_RequestInterruptCallback
|
||||
* is mostly safe--the only danger is that we might interrupt JS_NewContext or
|
||||
* JS_DestroyContext while the context list is being modified. Therefore we
|
||||
* disable the signal handler around calls to those functions.
|
||||
*/
|
||||
#ifdef JS_THREADSAFE
|
||||
# define WITH_SIGNALS_DISABLED(x) x
|
||||
#else
|
||||
# define WITH_SIGNALS_DISABLED(x) \
|
||||
JS_BEGIN_MACRO \
|
||||
ScheduleWatchdog(gRuntime, -1); \
|
||||
x; \
|
||||
ScheduleWatchdog(gRuntime, gTimeoutInterval); \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
static JSContext *
|
||||
NewContext(JSRuntime *rt)
|
||||
{
|
||||
JSContext *cx;
|
||||
WITH_SIGNALS_DISABLED(cx = JS_NewContext(rt, gStackChunkSize));
|
||||
JSContext *cx = JS_NewContext(rt, gStackChunkSize);
|
||||
if (!cx)
|
||||
return nullptr;
|
||||
|
||||
|
@ -5790,7 +5669,7 @@ DestroyContext(JSContext *cx, bool withGC)
|
|||
JSShellContextData *data = (JSShellContextData *) JS_GetContextPrivate(cx);
|
||||
JS_SetContextPrivate(cx, nullptr);
|
||||
free(data);
|
||||
WITH_SIGNALS_DISABLED(withGC ? JS_DestroyContext(cx) : JS_DestroyContextNoGC(cx));
|
||||
withGC ? JS_DestroyContext(cx) : JS_DestroyContextNoGC(cx);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
|
@ -6078,9 +5957,7 @@ SetRuntimeOptions(JSRuntime *rt, const OptionParser &op)
|
|||
else if (strcmp(str, "on") != 0)
|
||||
return OptionFailure("ion-offthread-compile", str);
|
||||
}
|
||||
#ifdef JS_THREADSAFE
|
||||
rt->setOffthreadIonCompilationEnabled(offthreadCompilation);
|
||||
#endif
|
||||
|
||||
if (op.getStringOption("ion-parallel-compile")) {
|
||||
fprintf(stderr, "--ion-parallel-compile is deprecated. Please use --ion-offthread-compile instead.\n");
|
||||
|
@ -6258,10 +6135,8 @@ main(int argc, char **argv, char **envp)
|
|||
|| !op.addOptionalMultiStringArg("scriptArgs",
|
||||
"String arguments to bind as |scriptArgs| in the "
|
||||
"shell's global")
|
||||
#ifdef JS_THREADSAFE
|
||||
|| !op.addIntOption('\0', "thread-count", "COUNT", "Use COUNT auxiliary threads "
|
||||
"(default: # of cores - 1)", -1)
|
||||
#endif
|
||||
|| !op.addBoolOption('\0', "ion", "Enable IonMonkey (default)")
|
||||
|| !op.addBoolOption('\0', "no-ion", "Disable IonMonkey")
|
||||
|| !op.addBoolOption('\0', "no-asmjs", "Disable asm.js compilation")
|
||||
|
@ -6398,13 +6273,11 @@ main(int argc, char **argv, char **envp)
|
|||
if (op.getBoolOption("no-threads"))
|
||||
js::DisableExtraThreads();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// The fake thread count must be set before initializing the Runtime,
|
||||
// which spins up the thread pool.
|
||||
int32_t threadCount = op.getIntOption("thread-count");
|
||||
if (threadCount >= 0)
|
||||
SetFakeCPUCount(threadCount);
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
// Start the engine.
|
||||
if (!JS_Init())
|
||||
|
@ -6446,10 +6319,8 @@ main(int argc, char **argv, char **envp)
|
|||
|
||||
JS_SetNativeStackQuota(rt, gMaxStackSize);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!offThreadState.init())
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if (!InitWatchdog(rt))
|
||||
return 1;
|
||||
|
@ -6476,11 +6347,9 @@ main(int argc, char **argv, char **envp)
|
|||
|
||||
gInterruptFunc.destroy();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
|
||||
for (size_t i = 0; i < workerThreads.length(); i++)
|
||||
PR_JoinThread(workerThreads[i]);
|
||||
#endif
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (!noggc.empty())
|
||||
|
|
|
@ -19,13 +19,10 @@
|
|||
#include "jsprf.h"
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "vm/Monitor.h"
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
# include "jit/BaselineJIT.h"
|
||||
# include "vm/Monitor.h"
|
||||
#endif
|
||||
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
# include "jit/JitCommon.h"
|
||||
# include "jit/RematerializedFrame.h"
|
||||
# ifdef FORKJOIN_SPEW
|
||||
|
@ -34,7 +31,7 @@
|
|||
# include "jit/MIR.h"
|
||||
# include "jit/MIRGraph.h"
|
||||
# endif
|
||||
#endif // THREADSAFE && ION
|
||||
#endif // JS_ION
|
||||
|
||||
#include "gc/ForkJoinNursery-inl.h"
|
||||
#include "vm/Interpreter-inl.h"
|
||||
|
@ -48,9 +45,8 @@ 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.
|
||||
// When 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, uint16_t *sliceStart,
|
||||
|
@ -68,7 +64,7 @@ ForkJoinSequentially(JSContext *cx, CallArgs &args)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if !defined(JS_THREADSAFE) || !defined(JS_ION)
|
||||
#if !defined(JS_ION)
|
||||
bool
|
||||
js::ForkJoin(JSContext *cx, CallArgs &args)
|
||||
{
|
||||
|
@ -176,7 +172,7 @@ intrinsic_ClearThreadLocalArenasPar(ForkJoinContext *cx, unsigned argc, Value *v
|
|||
JS_JITINFO_NATIVE_PARALLEL(js::intrinsic_ClearThreadLocalArenasInfo,
|
||||
intrinsic_ClearThreadLocalArenasPar);
|
||||
|
||||
#endif // !JS_THREADSAFE || !JS_ION
|
||||
#endif // !JS_ION
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// All configurations
|
||||
|
@ -217,10 +213,10 @@ ForkJoinContext::initializeTls()
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parallel configurations
|
||||
//
|
||||
// The remainder of this file is specific to cases where both
|
||||
// JS_THREADSAFE and JS_ION are enabled.
|
||||
// The remainder of this file is specific to cases where
|
||||
// JS_ION is enabled.
|
||||
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Class Declarations and Function Prototypes
|
||||
|
@ -2472,4 +2468,4 @@ intrinsic_ClearThreadLocalArenasPar(ForkJoinContext *cx, unsigned argc, Value *v
|
|||
JS_JITINFO_NATIVE_PARALLEL(js::intrinsic_ClearThreadLocalArenasInfo,
|
||||
intrinsic_ClearThreadLocalArenasPar);
|
||||
|
||||
#endif // JS_THREADSAFE && JS_ION
|
||||
#endif // JS_ION
|
||||
|
|
|
@ -523,14 +523,14 @@ class ForkJoinContext : public ThreadSafeContext
|
|||
// hold the lock to write).
|
||||
class LockedJSContext
|
||||
{
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
ForkJoinContext *cx_;
|
||||
#endif
|
||||
JSContext *jscx_;
|
||||
|
||||
public:
|
||||
explicit LockedJSContext(ForkJoinContext *cx)
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
: cx_(cx),
|
||||
jscx_(cx->acquireJSContext())
|
||||
#else
|
||||
|
@ -539,7 +539,7 @@ class LockedJSContext
|
|||
{ }
|
||||
|
||||
~LockedJSContext() {
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
cx_->releaseJSContext();
|
||||
#endif
|
||||
}
|
||||
|
@ -591,7 +591,7 @@ enum SpewChannel {
|
|||
NumSpewChannels
|
||||
};
|
||||
|
||||
#if defined(FORKJOIN_SPEW) && defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#if defined(FORKJOIN_SPEW) && defined(JS_ION)
|
||||
|
||||
bool SpewEnabled(SpewChannel channel);
|
||||
void Spew(SpewChannel channel, const char *fmt, ...);
|
||||
|
@ -619,7 +619,7 @@ static inline jit::MethodStatus SpewEndCompile(jit::MethodStatus status) { retur
|
|||
static inline void SpewMIR(jit::MDefinition *mir, const char *fmt, ...) { }
|
||||
#endif
|
||||
|
||||
#endif // FORKJOIN_SPEW && JS_THREADSAFE && JS_ION
|
||||
#endif // FORKJOIN_SPEW && JS_ION
|
||||
|
||||
} // namespace parallel
|
||||
} // namespace js
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#include "vm/HelperThreads.h"
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jsnativestack.h"
|
||||
|
@ -1246,74 +1244,3 @@ HelperThread::threadLoop()
|
|||
MOZ_CRASH("No task to perform");
|
||||
}
|
||||
}
|
||||
|
||||
#else /* JS_THREADSAFE */
|
||||
|
||||
using namespace js;
|
||||
|
||||
#ifdef JS_ION
|
||||
|
||||
bool
|
||||
js::StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData)
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available in non-THREADSAFE builds");
|
||||
}
|
||||
|
||||
bool
|
||||
js::StartOffThreadIonCompile(JSContext *cx, jit::IonBuilder *builder)
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available in non-THREADSAFE builds");
|
||||
}
|
||||
|
||||
#endif // JS_ION
|
||||
|
||||
void
|
||||
js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
js::CancelOffThreadParses(JSRuntime *rt)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &options,
|
||||
const jschar *chars, size_t length,
|
||||
JS::OffThreadCompileCallback callback, void *callbackData)
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available in non-THREADSAFE builds");
|
||||
}
|
||||
|
||||
bool
|
||||
js::StartOffThreadCompression(ExclusiveContext *cx, SourceCompressionTask *task)
|
||||
{
|
||||
MOZ_CRASH("Off thread compression not available");
|
||||
}
|
||||
|
||||
bool
|
||||
SourceCompressionTask::complete()
|
||||
{
|
||||
JS_ASSERT(!ss);
|
||||
return true;
|
||||
}
|
||||
|
||||
frontend::CompileError &
|
||||
ExclusiveContext::addPendingCompileError()
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available.");
|
||||
}
|
||||
|
||||
void
|
||||
ExclusiveContext::addPendingOverRecursed()
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available.");
|
||||
}
|
||||
|
||||
void
|
||||
js::PauseCurrentHelperThread()
|
||||
{
|
||||
MOZ_CRASH("Off thread compilation not available.");
|
||||
}
|
||||
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
|
|
@ -31,8 +31,6 @@ namespace jit {
|
|||
class IonBuilder;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
// Per-process state for off thread work items.
|
||||
class GlobalHelperThreadState
|
||||
{
|
||||
|
@ -103,9 +101,9 @@ class GlobalHelperThreadState
|
|||
void lock();
|
||||
void unlock();
|
||||
|
||||
# ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
bool isLocked();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
enum CondVar {
|
||||
// For notifying threads waiting for work that they may be able to make progress.
|
||||
|
@ -221,9 +219,9 @@ class GlobalHelperThreadState
|
|||
* used by all condition variables.
|
||||
*/
|
||||
PRLock *helperLock;
|
||||
# ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
PRThread *lockOwner;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Condvars for threads waiting/notifying each other. */
|
||||
PRCondVar *consumerWakeup;
|
||||
|
@ -309,8 +307,6 @@ struct HelperThread
|
|||
void threadLoop();
|
||||
};
|
||||
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
/* Methods for interacting with helper threads. */
|
||||
|
||||
// Initialize helper threads unless already initialized.
|
||||
|
@ -376,7 +372,6 @@ class AutoLockHelperThreadState
|
|||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
public:
|
||||
explicit AutoLockHelperThreadState(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
{
|
||||
|
@ -387,13 +382,6 @@ class AutoLockHelperThreadState
|
|||
~AutoLockHelperThreadState() {
|
||||
HelperThreadState().unlock();
|
||||
}
|
||||
#else
|
||||
public:
|
||||
AutoLockHelperThreadState(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class AutoUnlockHelperThreadState
|
||||
|
@ -405,16 +393,12 @@ class AutoUnlockHelperThreadState
|
|||
explicit AutoUnlockHelperThreadState(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef JS_THREADSAFE
|
||||
HelperThreadState().unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
~AutoUnlockHelperThreadState()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
HelperThreadState().lock();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -489,12 +473,10 @@ struct ParseTask
|
|||
~ParseTask();
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// Return whether, if a new parse task was started, it would need to wait for
|
||||
// an in-progress GC to complete before starting.
|
||||
extern bool
|
||||
OffThreadParsingMustWaitForGC(JSRuntime *rt);
|
||||
#endif
|
||||
|
||||
// Compression tasks are allocated on the stack by their triggering thread,
|
||||
// which will block on the compression completing as the task goes out of scope
|
||||
|
@ -504,10 +486,8 @@ struct SourceCompressionTask
|
|||
friend class ScriptSource;
|
||||
friend struct HelperThread;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
// Thread performing the compression.
|
||||
HelperThread *helperThread;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Context from the triggering thread. Don't use this off thread!
|
||||
|
@ -531,13 +511,9 @@ struct SourceCompressionTask
|
|||
|
||||
public:
|
||||
explicit SourceCompressionTask(ExclusiveContext *cx)
|
||||
: cx(cx), ss(nullptr), abort_(false),
|
||||
: helperThread(nullptr), cx(cx), ss(nullptr), abort_(false),
|
||||
result(OOM), compressed(nullptr), compressedBytes(0), compressedHash(0)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
helperThread = nullptr;
|
||||
#endif
|
||||
}
|
||||
{}
|
||||
|
||||
~SourceCompressionTask()
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ using namespace js;
|
|||
bool
|
||||
Monitor::init()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
lock_ = PR_NewLock();
|
||||
if (!lock_)
|
||||
return false;
|
||||
|
@ -19,7 +18,6 @@ Monitor::init()
|
|||
condVar_ = PR_NewCondVar(lock_);
|
||||
if (!condVar_)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
#ifndef vm_Monitor_h
|
||||
#define vm_Monitor_h
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
@ -40,12 +38,10 @@ class Monitor
|
|||
{ }
|
||||
|
||||
~Monitor() {
|
||||
#ifdef JS_THREADSAFE
|
||||
if (lock_)
|
||||
PR_DestroyLock(lock_);
|
||||
if (condVar_)
|
||||
PR_DestroyCondVar(condVar_);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool init();
|
||||
|
@ -54,106 +50,70 @@ class Monitor
|
|||
class AutoLockMonitor
|
||||
{
|
||||
private:
|
||||
#ifdef JS_THREADSAFE
|
||||
Monitor &monitor;
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit AutoLockMonitor(Monitor &monitor)
|
||||
#ifdef JS_THREADSAFE
|
||||
: monitor(monitor)
|
||||
{
|
||||
PR_Lock(monitor.lock_);
|
||||
}
|
||||
#else
|
||||
{}
|
||||
#endif
|
||||
|
||||
~AutoLockMonitor() {
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Unlock(monitor.lock_);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isFor(Monitor &other) const {
|
||||
#ifdef JS_THREADSAFE
|
||||
return monitor.lock_ == other.lock_;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait(PRCondVar *condVar) {
|
||||
#ifdef JS_THREADSAFE
|
||||
mozilla::DebugOnly<PRStatus> status =
|
||||
PR_WaitCondVar(condVar, PR_INTERVAL_NO_TIMEOUT);
|
||||
MOZ_ASSERT(status == PR_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait() {
|
||||
#ifdef JS_THREADSAFE
|
||||
wait(monitor.condVar_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void notify(PRCondVar *condVar) {
|
||||
#ifdef JS_THREADSAFE
|
||||
mozilla::DebugOnly<PRStatus> status = PR_NotifyCondVar(condVar);
|
||||
MOZ_ASSERT(status == PR_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void notify() {
|
||||
#ifdef JS_THREADSAFE
|
||||
notify(monitor.condVar_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void notifyAll(PRCondVar *condVar) {
|
||||
#ifdef JS_THREADSAFE
|
||||
mozilla::DebugOnly<PRStatus> status = PR_NotifyAllCondVar(monitor.condVar_);
|
||||
MOZ_ASSERT(status == PR_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void notifyAll() {
|
||||
#ifdef JS_THREADSAFE
|
||||
notifyAll(monitor.condVar_);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
class AutoUnlockMonitor
|
||||
{
|
||||
private:
|
||||
#ifdef JS_THREADSAFE
|
||||
Monitor &monitor;
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit AutoUnlockMonitor(Monitor &monitor)
|
||||
#ifdef JS_THREADSAFE
|
||||
: monitor(monitor)
|
||||
{
|
||||
PR_Unlock(monitor.lock_);
|
||||
}
|
||||
#else
|
||||
{}
|
||||
#endif
|
||||
|
||||
~AutoUnlockMonitor() {
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(monitor.lock_);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isFor(Monitor &other) const {
|
||||
#ifdef JS_THREADSAFE
|
||||
return monitor.lock_ == other.lock_;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
#ifdef JS_POSIX_NSPR
|
||||
|
||||
#ifndef JS_THREADSAFE
|
||||
#error "This file must not be included in non-threadsafe mode"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
|
@ -57,12 +57,7 @@ using JS::GenericNaN;
|
|||
using JS::DoubleNaNValue;
|
||||
|
||||
/* static */ ThreadLocal<PerThreadData*> js::TlsPerThreadData;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
/* static */ Atomic<size_t> JSRuntime::liveRuntimesCount;
|
||||
#else
|
||||
/* static */ size_t JSRuntime::liveRuntimesCount;
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
bool gCanUseExtraThreads = true;
|
||||
|
@ -137,28 +132,22 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
|
|||
mainThread(this),
|
||||
parentRuntime(parentRuntime),
|
||||
interrupt(false),
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
interruptPar(false),
|
||||
#endif
|
||||
handlingSignal(false),
|
||||
interruptCallback(nullptr),
|
||||
#ifdef JS_THREADSAFE
|
||||
interruptLock(nullptr),
|
||||
interruptLockOwner(nullptr),
|
||||
exclusiveAccessLock(nullptr),
|
||||
exclusiveAccessOwner(nullptr),
|
||||
mainThreadHasExclusiveAccess(false),
|
||||
numExclusiveThreads(0),
|
||||
#else
|
||||
interruptLockTaken(false),
|
||||
#endif
|
||||
numCompartments(0),
|
||||
localeCallbacks(nullptr),
|
||||
defaultLocale(nullptr),
|
||||
defaultVersion_(JSVERSION_DEFAULT),
|
||||
#ifdef JS_THREADSAFE
|
||||
ownerThread_(nullptr),
|
||||
#endif
|
||||
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
execAlloc_(nullptr),
|
||||
|
@ -172,13 +161,9 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
|
|||
compartmentNameCallback(nullptr),
|
||||
activityCallback(nullptr),
|
||||
activityCallbackArg(nullptr),
|
||||
#ifdef JS_THREADSAFE
|
||||
requestDepth(0),
|
||||
# ifdef DEBUG
|
||||
checkRequestDepth(0),
|
||||
# endif
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
checkRequestDepth(0),
|
||||
activeContext(nullptr),
|
||||
#endif
|
||||
gc(thisFromCtor()),
|
||||
|
@ -281,7 +266,6 @@ SignalBasedTriggersDisabled()
|
|||
bool
|
||||
JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
ownerThread_ = PR_GetCurrentThread();
|
||||
|
||||
interruptLock = PR_NewLock();
|
||||
|
@ -291,7 +275,6 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
|
|||
exclusiveAccessLock = PR_NewLock();
|
||||
if (!exclusiveAccessLock)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!mainThread.init())
|
||||
return false;
|
||||
|
@ -415,7 +398,6 @@ JSRuntime::~JSRuntime()
|
|||
*/
|
||||
finishSelfHosting();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!exclusiveAccessOwner);
|
||||
if (exclusiveAccessLock)
|
||||
PR_DestroyLock(exclusiveAccessLock);
|
||||
|
@ -427,7 +409,6 @@ JSRuntime::~JSRuntime()
|
|||
JS_ASSERT(!interruptLockOwner);
|
||||
if (interruptLock)
|
||||
PR_DestroyLock(interruptLock);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Even though all objects in the compartment are dead, we may have keep
|
||||
|
@ -479,9 +460,7 @@ JSRuntime::~JSRuntime()
|
|||
DebugOnly<size_t> oldCount = liveRuntimesCount--;
|
||||
JS_ASSERT(oldCount > 0);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
js::TlsPerThreadData.set(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -584,9 +563,7 @@ JSRuntime::requestInterrupt(InterruptMode mode)
|
|||
interrupt = true;
|
||||
|
||||
#ifdef JS_ION
|
||||
#ifdef JS_THREADSAFE
|
||||
RequestInterruptForForkJoin(this, mode);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* asm.js and normal Ion code optionally use memory protection and signal
|
||||
|
@ -754,8 +731,6 @@ JSRuntime::activeGCInAtomsZone()
|
|||
return zone->needsBarrier() || zone->isGCScheduled() || zone->wasGCStarted();
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
void
|
||||
JSRuntime::setUsedByExclusiveThread(Zone *zone)
|
||||
{
|
||||
|
@ -795,28 +770,11 @@ js::CurrentThreadCanAccessZone(Zone *zone)
|
|||
return zone->usedByExclusiveThread;
|
||||
}
|
||||
|
||||
#else // JS_THREADSAFE
|
||||
|
||||
bool
|
||||
js::CurrentThreadCanAccessRuntime(JSRuntime *rt)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::CurrentThreadCanAccessZone(Zone *zone)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void
|
||||
JSRuntime::assertCanLock(RuntimeLock which)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
// In the switch below, each case falls through to the one below it. None
|
||||
// of the runtime locks are reentrant, and when multiple locks are acquired
|
||||
// it must be done in the order below.
|
||||
|
@ -833,17 +791,14 @@ JSRuntime::assertCanLock(RuntimeLock which)
|
|||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
void
|
||||
js::AssertCurrentThreadCanLock(RuntimeLock which)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
PerThreadData *pt = TlsPerThreadData.get();
|
||||
if (pt && pt->runtime_)
|
||||
pt->runtime_->assertCanLock(which);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
|
|
@ -720,7 +720,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
*/
|
||||
mozilla::Atomic<bool, mozilla::Relaxed> interrupt;
|
||||
|
||||
#if defined(JS_THREADSAFE) && defined(JS_ION)
|
||||
#ifdef JS_ION
|
||||
/*
|
||||
* If non-zero, ForkJoin should service an interrupt. This is a separate
|
||||
* flag from |interrupt| because we cannot use the mprotect trick with PJS
|
||||
|
@ -745,50 +745,32 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
* Lock taken when triggering an interrupt from another thread.
|
||||
* Protects all data that is touched in this process.
|
||||
*/
|
||||
#ifdef JS_THREADSAFE
|
||||
PRLock *interruptLock;
|
||||
PRThread *interruptLockOwner;
|
||||
#else
|
||||
bool interruptLockTaken;
|
||||
#endif // JS_THREADSAFE
|
||||
public:
|
||||
|
||||
public:
|
||||
class AutoLockForInterrupt {
|
||||
JSRuntime *rt;
|
||||
public:
|
||||
explicit AutoLockForInterrupt(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : rt(rt) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
rt->assertCanLock(js::InterruptLock);
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(rt->interruptLock);
|
||||
rt->interruptLockOwner = PR_GetCurrentThread();
|
||||
#else
|
||||
rt->interruptLockTaken = true;
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
~AutoLockForInterrupt() {
|
||||
JS_ASSERT(rt->currentThreadOwnsInterruptLock());
|
||||
#ifdef JS_THREADSAFE
|
||||
rt->interruptLockOwner = nullptr;
|
||||
PR_Unlock(rt->interruptLock);
|
||||
#else
|
||||
rt->interruptLockTaken = false;
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
bool currentThreadOwnsInterruptLock() {
|
||||
#if defined(JS_THREADSAFE)
|
||||
return interruptLockOwner == PR_GetCurrentThread();
|
||||
#else
|
||||
return interruptLockTaken;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
private:
|
||||
/*
|
||||
* Lock taken when using per-runtime or per-zone data that could otherwise
|
||||
|
@ -811,25 +793,15 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
void setUsedByExclusiveThread(JS::Zone *zone);
|
||||
void clearUsedByExclusiveThread(JS::Zone *zone);
|
||||
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
#ifdef DEBUG
|
||||
bool currentThreadHasExclusiveAccess() {
|
||||
#ifdef JS_THREADSAFE
|
||||
return (!numExclusiveThreads && mainThreadHasExclusiveAccess) ||
|
||||
exclusiveAccessOwner == PR_GetCurrentThread();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
bool exclusiveThreadsPresent() const {
|
||||
#ifdef JS_THREADSAFE
|
||||
return numExclusiveThreads > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* How many compartments there are across all zones. */
|
||||
|
@ -844,13 +816,11 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
/* Default JSVersion. */
|
||||
JSVersion defaultVersion_;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
private:
|
||||
/* See comment for JS_AbortIfWrongThread in jsapi.h. */
|
||||
void *ownerThread_;
|
||||
friend bool js::CurrentThreadCanAccessRuntime(JSRuntime *rt);
|
||||
public:
|
||||
#endif
|
||||
|
||||
/* Temporary arena pool used while compiling and decompiling. */
|
||||
static const size_t TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 4 * 1024;
|
||||
|
@ -970,16 +940,12 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
void *activityCallbackArg;
|
||||
void triggerActivityCallback(bool active);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
/* The request depth for this thread. */
|
||||
unsigned requestDepth;
|
||||
|
||||
# ifdef DEBUG
|
||||
unsigned checkRequestDepth;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned checkRequestDepth;
|
||||
|
||||
/*
|
||||
* To help embedders enforce their invariants, we allow them to specify in
|
||||
* advance which JSContext should be passed to JSAPI calls. If this is set
|
||||
|
@ -1317,11 +1283,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
uint32_t forkJoinWarmup;
|
||||
|
||||
private:
|
||||
#ifdef JS_THREADSAFE
|
||||
static mozilla::Atomic<size_t> liveRuntimesCount;
|
||||
#else
|
||||
static size_t liveRuntimesCount;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static bool hasLiveRuntimes() {
|
||||
|
@ -1395,21 +1357,13 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
offthreadIonCompilationEnabled_ = value;
|
||||
}
|
||||
bool canUseOffthreadIonCompilation() const {
|
||||
#ifdef JS_THREADSAFE
|
||||
return offthreadIonCompilationEnabled_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
void setParallelParsingEnabled(bool value) {
|
||||
parallelParsingEnabled_ = value;
|
||||
}
|
||||
bool canUseParallelParsing() const {
|
||||
#ifdef JS_THREADSAFE
|
||||
return parallelParsingEnabled_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const JS::RuntimeOptions &options() const {
|
||||
|
@ -1740,7 +1694,7 @@ class AutoEnterIonCompilation
|
|||
AutoEnterIonCompilation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
#if defined(DEBUG) && defined(JS_THREADSAFE)
|
||||
#ifdef DEBUG
|
||||
PerThreadData *pt = js::TlsPerThreadData.get();
|
||||
JS_ASSERT(!pt->ionCompiling);
|
||||
pt->ionCompiling = true;
|
||||
|
@ -1748,7 +1702,7 @@ class AutoEnterIonCompilation
|
|||
}
|
||||
|
||||
~AutoEnterIonCompilation() {
|
||||
#if defined(DEBUG) && defined(JS_THREADSAFE)
|
||||
#ifdef DEBUG
|
||||
PerThreadData *pt = js::TlsPerThreadData.get();
|
||||
JS_ASSERT(pt->ionCompiling);
|
||||
pt->ionCompiling = false;
|
||||
|
|
|
@ -35,11 +35,10 @@ SPSProfiler::SPSProfiler(JSRuntime *rt)
|
|||
bool
|
||||
SPSProfiler::init()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
lock_ = PR_NewLock();
|
||||
if (lock_ == nullptr)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -49,10 +48,8 @@ SPSProfiler::~SPSProfiler()
|
|||
for (ProfileStringMap::Enum e(strings); !e.empty(); e.popFront())
|
||||
js_free(const_cast<char *>(e.front().value()));
|
||||
}
|
||||
#ifdef JS_THREADSAFE
|
||||
if (lock_)
|
||||
PR_DestroyLock(lock_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -208,7 +208,6 @@ class SPSProfiler
|
|||
class AutoSPSLock
|
||||
{
|
||||
public:
|
||||
#ifdef JS_THREADSAFE
|
||||
explicit AutoSPSLock(PRLock *lock)
|
||||
{
|
||||
MOZ_ASSERT(lock, "Parameter should not be null!");
|
||||
|
@ -216,9 +215,6 @@ class AutoSPSLock
|
|||
PR_Lock(lock);
|
||||
}
|
||||
~AutoSPSLock() { PR_Unlock(lock_); }
|
||||
#else
|
||||
explicit AutoSPSLock(PRLock *) {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
PRLock *lock_;
|
||||
|
|
|
@ -670,12 +670,8 @@ bool
|
|||
js::intrinsic_ShouldForceSequential(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
#ifdef JS_THREADSAFE
|
||||
args.rval().setBoolean(cx->runtime()->forkJoinWarmup ||
|
||||
InParallelSection());
|
||||
#else
|
||||
args.rval().setBoolean(true);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -130,9 +130,6 @@ ThreadPoolWorker::randomWorker()
|
|||
bool
|
||||
ThreadPoolWorker::start()
|
||||
{
|
||||
#ifndef JS_THREADSAFE
|
||||
return false;
|
||||
#else
|
||||
if (isMainThread())
|
||||
return true;
|
||||
|
||||
|
@ -148,7 +145,6 @@ ThreadPoolWorker::start()
|
|||
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
WORKER_THREAD_STACK_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
|
@ -278,18 +274,15 @@ ThreadPool::~ThreadPool()
|
|||
terminateWorkers();
|
||||
if (chunkLock_)
|
||||
clearChunkCache();
|
||||
#ifdef JS_THREADSAFE
|
||||
if (chunkLock_)
|
||||
PR_DestroyLock(chunkLock_);
|
||||
if (joinBarrier_)
|
||||
PR_DestroyCondVar(joinBarrier_);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPool::init()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!Monitor::init())
|
||||
return false;
|
||||
joinBarrier_ = PR_NewCondVar(lock_);
|
||||
|
@ -298,18 +291,13 @@ ThreadPool::init()
|
|||
chunkLock_ = PR_NewLock();
|
||||
if (!chunkLock_)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ThreadPool::numWorkers() const
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return HelperThreadState().cpuCount;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -334,7 +322,6 @@ ThreadPool::lazyStartWorkers(JSContext *cx)
|
|||
// from this function, the workers array is either full (upon
|
||||
// success) or empty (upon failure).
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!workers_.empty()) {
|
||||
MOZ_ASSERT(workers_.length() == numWorkers());
|
||||
return true;
|
||||
|
@ -363,7 +350,6 @@ ThreadPool::lazyStartWorkers(JSContext *cx)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -718,11 +718,9 @@ TraceLogging::TraceLogging()
|
|||
offThreadEnabled = true;
|
||||
loggerId = 0;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
lock = PR_NewLock();
|
||||
if (!lock)
|
||||
MOZ_CRASH();
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
TraceLogging::~TraceLogging()
|
||||
|
@ -738,7 +736,6 @@ TraceLogging::~TraceLogging()
|
|||
|
||||
mainThreadLoggers.clear();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (threadLoggers.initialized()) {
|
||||
for (ThreadLoggerHashMap::Range r = threadLoggers.all(); !r.empty(); r.popFront())
|
||||
delete r.front().value();
|
||||
|
@ -750,7 +747,6 @@ TraceLogging::~TraceLogging()
|
|||
PR_DestroyLock(lock);
|
||||
lock = nullptr;
|
||||
}
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
enabled = false;
|
||||
}
|
||||
|
@ -781,10 +777,8 @@ TraceLogging::lazyInit()
|
|||
return false;
|
||||
fprintf(out, "[");
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!threadLoggers.init())
|
||||
return false;
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
const char *env = getenv("TLLOG");
|
||||
if (!env)
|
||||
|
@ -935,15 +929,10 @@ TraceLogging::forMainThread(PerThreadData *mainThread)
|
|||
TraceLogger *
|
||||
js::TraceLoggerForCurrentThread()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
PRThread *thread = PR_GetCurrentThread();
|
||||
return traceLoggers.forThread(thread);
|
||||
#else
|
||||
MOZ_CRASH("No threads supported. Use TraceLoggerForMainThread for the main thread.");
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
TraceLogger *
|
||||
TraceLogging::forThread(PRThread *thread)
|
||||
{
|
||||
|
@ -970,7 +959,6 @@ TraceLogging::forThread(PRThread *thread)
|
|||
|
||||
return logger;
|
||||
}
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
TraceLogger *
|
||||
TraceLogging::create()
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
#ifndef TraceLogging_h
|
||||
#define TraceLogging_h
|
||||
|
||||
#include "jsalloc.h"
|
||||
#ifdef JS_THREADSAFE
|
||||
# include "jslock.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Vector.h"
|
||||
|
@ -470,12 +468,10 @@ class TraceLogger
|
|||
class TraceLogging
|
||||
{
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
#ifdef JS_THREADSAFE
|
||||
typedef HashMap<PRThread *,
|
||||
TraceLogger *,
|
||||
PointerHasher<PRThread *, 3>,
|
||||
SystemAllocPolicy> ThreadLoggerHashMap;
|
||||
#endif // JS_THREADSAFE
|
||||
typedef Vector<TraceLogger *, 1, js::SystemAllocPolicy > MainThreadLoggers;
|
||||
|
||||
bool initialized;
|
||||
|
@ -483,27 +479,21 @@ class TraceLogging
|
|||
bool enabledTextIds[TraceLogger::LAST];
|
||||
bool mainThreadEnabled;
|
||||
bool offThreadEnabled;
|
||||
#ifdef JS_THREADSAFE
|
||||
ThreadLoggerHashMap threadLoggers;
|
||||
#endif // JS_THREADSAFE
|
||||
MainThreadLoggers mainThreadLoggers;
|
||||
uint32_t loggerId;
|
||||
FILE *out;
|
||||
|
||||
public:
|
||||
uint64_t startupTime;
|
||||
#ifdef JS_THREADSAFE
|
||||
PRLock *lock;
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
TraceLogging();
|
||||
~TraceLogging();
|
||||
|
||||
TraceLogger *forMainThread(JSRuntime *runtime);
|
||||
TraceLogger *forMainThread(jit::CompileRuntime *runtime);
|
||||
#ifdef JS_THREADSAFE
|
||||
TraceLogger *forThread(PRThread *thread);
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
bool isTextIdEnabled(uint32_t textId) {
|
||||
if (textId < TraceLogger::LAST)
|
||||
|
@ -667,14 +657,10 @@ class AutoTraceLoggingLock
|
|||
: logging(logging)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Lock(logging->lock);
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
~AutoTraceLoggingLock() {
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_Unlock(logging->lock);
|
||||
#endif // JS_THREADSAFE
|
||||
}
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
|
|
@ -90,14 +90,6 @@ private:
|
|||
nsCOMPtr<nsIFile> mAppFile;
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#define DoBeginRequest(cx) JS_BeginRequest((cx))
|
||||
#define DoEndRequest(cx) JS_EndRequest((cx))
|
||||
#else
|
||||
#define DoBeginRequest(cx) ((void)0)
|
||||
#define DoEndRequest(cx) ((void)0)
|
||||
#endif
|
||||
|
||||
static const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1";
|
||||
|
||||
#define EXITCODE_RUNTIME_ERROR 3
|
||||
|
@ -920,7 +912,7 @@ ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj, const char *filename, FILE
|
|||
}
|
||||
}
|
||||
ungetc(ch, file);
|
||||
DoBeginRequest(cx);
|
||||
JS_BeginRequest(cx);
|
||||
|
||||
JS::CompileOptions options(cx);
|
||||
options.setUTF8(true)
|
||||
|
@ -928,7 +920,7 @@ ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj, const char *filename, FILE
|
|||
.setCompileAndGo(true);
|
||||
if (JS::Compile(cx, obj, options, file, &script) && !compileOnly)
|
||||
(void)JS_ExecuteScript(cx, obj, script, &result);
|
||||
DoEndRequest(cx);
|
||||
JS_EndRequest(cx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -956,7 +948,7 @@ ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj, const char *filename, FILE
|
|||
lineno++;
|
||||
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
|
||||
|
||||
DoBeginRequest(cx);
|
||||
JS_BeginRequest(cx);
|
||||
/* Clear any pending exception from previous failed compiles. */
|
||||
JS_ClearPendingException(cx);
|
||||
JS::CompileOptions options(cx);
|
||||
|
@ -980,7 +972,7 @@ ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj, const char *filename, FILE
|
|||
}
|
||||
}
|
||||
}
|
||||
DoEndRequest(cx);
|
||||
JS_EndRequest(cx);
|
||||
} while (!hitEOF && !gQuitting);
|
||||
|
||||
fprintf(gOutFile, "\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче