Bug 1031529 part 2 - Remove JS_THREADSAFE #ifdefs everywhere. r=bhackett

This commit is contained in:
Jan de Mooij 2014-07-24 11:56:43 +02:00
Родитель 24bccfb24b
Коммит 9dd0f57269
45 изменённых файлов: 56 добавлений и 781 удалений

Просмотреть файл

@ -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");