зеркало из https://github.com/mozilla/gecko-dev.git
Bug 853862 - Wrap ionStackLimit modifications with a lock. r=jandem,h4writer
This commit is contained in:
Родитель
478acd0f98
Коммит
ef4a0edc38
|
@ -398,7 +398,6 @@ IonActivation::IonActivation(JSContext *cx, StackFrame *fp)
|
|||
fp->setRunningInIon();
|
||||
cx->mainThread().ionJSContext = cx;
|
||||
cx->mainThread().ionActivation = this;
|
||||
cx->mainThread().ionStackLimit = cx->mainThread().nativeStackLimit;
|
||||
}
|
||||
|
||||
IonActivation::~IonActivation()
|
||||
|
|
|
@ -689,11 +689,14 @@ PerThreadData::PerThreadData(JSRuntime *runtime)
|
|||
ionTop(NULL),
|
||||
ionJSContext(NULL),
|
||||
ionStackLimit(0),
|
||||
#ifdef JS_THREADSAFE
|
||||
ionStackLimitLock_(NULL),
|
||||
#endif
|
||||
ionActivation(NULL),
|
||||
asmJSActivationStack_(NULL),
|
||||
# ifdef JS_THREADSAFE
|
||||
#ifdef JS_THREADSAFE
|
||||
asmJSActivationStackLock_(NULL),
|
||||
# endif
|
||||
#endif
|
||||
suppressGC(0)
|
||||
{}
|
||||
|
||||
|
@ -701,6 +704,10 @@ bool
|
|||
PerThreadData::init()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
ionStackLimitLock_ = PR_NewLock();
|
||||
if (!ionStackLimitLock_)
|
||||
return false;
|
||||
|
||||
asmJSActivationStackLock_ = PR_NewLock();
|
||||
if (!asmJSActivationStackLock_)
|
||||
return false;
|
||||
|
@ -711,6 +718,9 @@ PerThreadData::init()
|
|||
PerThreadData::~PerThreadData()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (ionStackLimitLock_)
|
||||
PR_DestroyLock(ionStackLimitLock_);
|
||||
|
||||
if (asmJSActivationStackLock_)
|
||||
PR_DestroyLock(asmJSActivationStackLock_);
|
||||
#endif
|
||||
|
@ -3032,6 +3042,16 @@ JS_SetNativeStackQuota(JSRuntime *rt, size_t stackSize)
|
|||
rt->mainThread.nativeStackLimit = rt->nativeStackBase - (stackSize - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// If there's no pending interrupt request set on the runtime's main thread's
|
||||
// ionStackLimit, then update it so that it reflects the new nativeStacklimit.
|
||||
#ifdef JS_ION
|
||||
{
|
||||
PerThreadData::IonStackLimitLock lock(rt->mainThread);
|
||||
if (rt->mainThread.ionStackLimit != -1)
|
||||
rt->mainThread.ionStackLimit = rt->mainThread.nativeStackLimit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
|
|
@ -168,7 +168,7 @@ JSRuntime::triggerOperationCallback()
|
|||
* into a weird state where interrupt is stuck at 0 but ionStackLimit is
|
||||
* MAXADDR.
|
||||
*/
|
||||
mainThread.ionStackLimit = -1;
|
||||
mainThread.setIonStackLimit(-1);
|
||||
|
||||
/*
|
||||
* Use JS_ATOMIC_SET in the hope that it ensures the write will become
|
||||
|
|
|
@ -483,6 +483,35 @@ class PerThreadData : public js::PerThreadDataFriendFields
|
|||
JSContext *ionJSContext;
|
||||
uintptr_t ionStackLimit;
|
||||
|
||||
# ifdef JS_THREADSAFE
|
||||
/*
|
||||
* Synchronizes setting of ionStackLimit so signals by triggerOperationCallback don't
|
||||
* get lost.
|
||||
*/
|
||||
PRLock *ionStackLimitLock_;
|
||||
|
||||
class IonStackLimitLock {
|
||||
PerThreadData &data_;
|
||||
public:
|
||||
IonStackLimitLock(PerThreadData &data) : data_(data) {
|
||||
JS_ASSERT(data_.ionStackLimitLock_);
|
||||
PR_Lock(data_.ionStackLimitLock_);
|
||||
}
|
||||
~IonStackLimitLock() {
|
||||
JS_ASSERT(data_.ionStackLimitLock_);
|
||||
PR_Unlock(data_.ionStackLimitLock_);
|
||||
}
|
||||
};
|
||||
#else
|
||||
class IonStackLimitLock {
|
||||
IonStackLimitLock(PerThreadData &data) {}
|
||||
};
|
||||
# endif
|
||||
void setIonStackLimit(uintptr_t limit) {
|
||||
IonStackLimitLock lock(*this);
|
||||
ionStackLimit = limit;
|
||||
}
|
||||
|
||||
/*
|
||||
* This points to the most recent Ion activation running on the thread.
|
||||
*/
|
||||
|
@ -1254,8 +1283,10 @@ struct JSRuntime : js::RuntimeFriendFields,
|
|||
|
||||
bool jitHardening;
|
||||
|
||||
// Used to reset stack limit after a signaled interrupt (i.e. ionStackLimit_ = -1)
|
||||
// has been noticed by Ion/Baseline.
|
||||
void resetIonStackLimit() {
|
||||
mainThread.ionStackLimit = mainThread.nativeStackLimit;
|
||||
mainThread.setIonStackLimit(mainThread.nativeStackLimit);
|
||||
}
|
||||
|
||||
// Cache for ion::GetPcScript().
|
||||
|
|
|
@ -289,6 +289,8 @@ ForkJoinShared::executeFromWorker(uint32_t workerId, uintptr_t stackLimit)
|
|||
|
||||
PerThreadData thisThread(cx_->runtime);
|
||||
TlsPerThreadData.set(&thisThread);
|
||||
// Don't use setIonStackLimit() because that acquires the ionStackLimitLock, and the
|
||||
// lock has not been initialized in these cases.
|
||||
thisThread.ionStackLimit = stackLimit;
|
||||
executePortion(&thisThread, workerId);
|
||||
TlsPerThreadData.set(NULL);
|
||||
|
@ -549,6 +551,9 @@ ForkJoinSlice::triggerAbort()
|
|||
// In principle, we probably ought to set the ionStackLimit's for
|
||||
// the other threads too, but right now the various slice objects
|
||||
// are not on a central list so that's not possible.
|
||||
|
||||
// Don't use setIonStackLimit() because that acquires the ionStackLimitLock, and the
|
||||
// lock has not been initialized in these cases.
|
||||
perThreadData->ionStackLimit = -1;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче