mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 723021 - moving native stack limits into runtime. r=luke
This commit is contained in:
parent
efea287c85
commit
bd4db6e9ef
@ -866,8 +866,6 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
|
||||
|
||||
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
|
||||
|
||||
JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
|
||||
|
||||
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
|
||||
JS_SetVersion(cx, JSVERSION_LATEST);
|
||||
JS_SetErrorReporter(cx, ContentScriptErrorReporter);
|
||||
|
@ -293,6 +293,8 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
JS_SetGCParameter(runtime, JSGC_MAX_BYTES,
|
||||
aWorkerPrivate->GetJSRuntimeHeapSize());
|
||||
|
||||
JS_SetNativeStackQuota(runtime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
|
||||
|
||||
JSContext* workerCx = JS_NewContext(runtime, 0);
|
||||
if (!workerCx) {
|
||||
JS_DestroyRuntime(runtime);
|
||||
@ -306,8 +308,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
|
||||
JS_SetOperationCallback(workerCx, OperationCallback);
|
||||
|
||||
JS_SetNativeStackQuota(workerCx, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
|
||||
|
||||
NS_ASSERTION((aWorkerPrivate->GetJSContextOptions() &
|
||||
kRequiredJSContextOptions) == kRequiredJSContextOptions,
|
||||
"Somehow we lost our required options!");
|
||||
|
@ -338,7 +338,25 @@ class JSAPITest
|
||||
}
|
||||
|
||||
virtual JSRuntime * createRuntime() {
|
||||
return JS_NewRuntime(8L * 1024 * 1024);
|
||||
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024);
|
||||
if (!rt)
|
||||
return NULL;
|
||||
|
||||
const size_t MAX_STACK_SIZE =
|
||||
/* Assume we can't use more than 5e5 bytes of C stack by default. */
|
||||
#if (defined(DEBUG) && defined(__SUNPRO_CC)) || defined(JS_CPU_SPARC)
|
||||
/*
|
||||
* Sun compiler uses a larger stack space for js::Interpret() with
|
||||
* debug. Use a bigger gMaxStackSize to make "make check" happy.
|
||||
*/
|
||||
5000000
|
||||
#else
|
||||
500000
|
||||
#endif
|
||||
;
|
||||
|
||||
JS_SetNativeStackQuota(rt, MAX_STACK_SIZE);
|
||||
return rt;
|
||||
}
|
||||
|
||||
virtual void destroyRuntime() {
|
||||
@ -358,22 +376,6 @@ class JSAPITest
|
||||
JSContext *cx = JS_NewContext(rt, 8192);
|
||||
if (!cx)
|
||||
return NULL;
|
||||
|
||||
const size_t MAX_STACK_SIZE =
|
||||
/* Assume we can't use more than 5e5 bytes of C stack by default. */
|
||||
#if (defined(DEBUG) && defined(__SUNPRO_CC)) || defined(JS_CPU_SPARC)
|
||||
/*
|
||||
* Sun compiler uses a larger stack space for js::Interpret() with
|
||||
* debug. Use a bigger gMaxStackSize to make "make check" happy.
|
||||
*/
|
||||
5000000
|
||||
#else
|
||||
500000
|
||||
#endif
|
||||
;
|
||||
|
||||
JS_SetNativeStackQuota(cx, MAX_STACK_SIZE);
|
||||
|
||||
JS_SetOptions(cx, JSOPTION_VAROBJFIX);
|
||||
JS_SetVersion(cx, JSVERSION_LATEST);
|
||||
JS_SetErrorReporter(cx, &reportError);
|
||||
@ -432,7 +434,7 @@ class JSAPITest
|
||||
|
||||
/*
|
||||
* A class for creating and managing one temporary file.
|
||||
*
|
||||
*
|
||||
* We could use the ISO C temporary file functions here, but those try to
|
||||
* create files in the root directory on Windows, which fails for users
|
||||
* without Administrator privileges.
|
||||
@ -463,7 +465,7 @@ class TempFile {
|
||||
fprintf(stderr, "error opening temporary file '%s': %s\n",
|
||||
fileName, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
name = fileName;
|
||||
return stream;
|
||||
}
|
||||
|
@ -694,8 +694,7 @@ JS_IsBuiltinFunctionConstructor(JSFunction *fun)
|
||||
static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
||||
|
||||
JSRuntime::JSRuntime()
|
||||
: interrupt(0),
|
||||
atomsCompartment(NULL),
|
||||
: atomsCompartment(NULL),
|
||||
#ifdef JS_THREADSAFE
|
||||
ownerThread_(NULL),
|
||||
#endif
|
||||
@ -703,6 +702,8 @@ JSRuntime::JSRuntime()
|
||||
execAlloc_(NULL),
|
||||
bumpAlloc_(NULL),
|
||||
repCache_(NULL),
|
||||
nativeStackBase(0),
|
||||
nativeStackQuota(0),
|
||||
interpreterFrames(NULL),
|
||||
cxCallback(NULL),
|
||||
compartmentCallback(NULL),
|
||||
@ -795,6 +796,10 @@ JSRuntime::JSRuntime()
|
||||
|
||||
PodZero(&globalDebugHooks);
|
||||
PodZero(&atomState);
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
nativeStackLimit = UINTPTR_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@ -834,7 +839,7 @@ JSRuntime::init(uint32_t maxbytes)
|
||||
if (!stackSpace.init())
|
||||
return false;
|
||||
|
||||
conservativeGC.nativeStackBase = GetNativeStackBase();
|
||||
nativeStackBase = GetNativeStackBase();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -883,7 +888,9 @@ JSRuntime::setOwnerThread()
|
||||
JS_ASSERT(ownerThread_ == (void *)0xc1ea12); /* "clear" */
|
||||
JS_ASSERT(requestDepth == 0);
|
||||
ownerThread_ = PR_GetCurrentThread();
|
||||
conservativeGC.nativeStackBase = GetNativeStackBase();
|
||||
nativeStackBase = GetNativeStackBase();
|
||||
if (nativeStackQuota)
|
||||
JS_SetNativeStackQuota(this, nativeStackQuota);
|
||||
}
|
||||
|
||||
void
|
||||
@ -892,7 +899,12 @@ JSRuntime::clearOwnerThread()
|
||||
JS_ASSERT(onOwnerThread());
|
||||
JS_ASSERT(requestDepth == 0);
|
||||
ownerThread_ = (void *)0xc1ea12; /* "clear" */
|
||||
conservativeGC.nativeStackBase = 0;
|
||||
nativeStackBase = 0;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
nativeStackLimit = UINTPTR_MAX;
|
||||
#else
|
||||
nativeStackLimit = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
@ -3002,33 +3014,25 @@ JS_GetExternalStringClosure(JSContext *cx, JSString *str)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetThreadStackLimit(JSContext *cx, uintptr_t limitAddr)
|
||||
{
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
if (limitAddr == 0)
|
||||
limitAddr = UINTPTR_MAX;
|
||||
#endif
|
||||
cx->stackLimit = limitAddr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetNativeStackQuota(JSContext *cx, size_t stackSize)
|
||||
JS_SetNativeStackQuota(JSRuntime *rt, size_t stackSize)
|
||||
{
|
||||
rt->nativeStackQuota = stackSize;
|
||||
if (!rt->nativeStackBase)
|
||||
return;
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
if (stackSize == 0) {
|
||||
cx->stackLimit = UINTPTR_MAX;
|
||||
rt->nativeStackLimit = UINTPTR_MAX;
|
||||
} else {
|
||||
uintptr_t stackBase = cx->runtime->nativeStackBase;
|
||||
JS_ASSERT(stackBase <= size_t(-1) - stackSize);
|
||||
cx->stackLimit = stackBase + stackSize - 1;
|
||||
JS_ASSERT(rt->nativeStackBase <= size_t(-1) - stackSize);
|
||||
rt->nativeStackLimit = rt->nativeStackBase + stackSize - 1;
|
||||
}
|
||||
#else
|
||||
if (stackSize == 0) {
|
||||
cx->stackLimit = 0;
|
||||
rt->nativeStackLimit = 0;
|
||||
} else {
|
||||
uintptr_t stackBase = uintptr_t(cx->runtime->conservativeGC.nativeStackBase);
|
||||
JS_ASSERT(stackBase >= stackSize);
|
||||
cx->stackLimit = stackBase - (stackSize - 1);
|
||||
JS_ASSERT(rt->nativeStackBase >= stackSize);
|
||||
rt->nativeStackLimit = rt->nativeStackBase - (stackSize - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -3370,18 +3370,12 @@ JS_IsExternalString(JSContext *cx, JSString *str);
|
||||
extern JS_PUBLIC_API(void *)
|
||||
JS_GetExternalStringClosure(JSContext *cx, JSString *str);
|
||||
|
||||
/*
|
||||
* Deprecated. Use JS_SetNativeStackQuoata instead.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetThreadStackLimit(JSContext *cx, uintptr_t limitAddr);
|
||||
|
||||
/*
|
||||
* Set the size of the native stack that should not be exceed. To disable
|
||||
* stack size checking pass 0.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetNativeStackQuota(JSContext *cx, size_t stackSize);
|
||||
JS_SetNativeStackQuota(JSRuntime *cx, size_t stackSize);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
@ -963,7 +963,8 @@ DSTOffsetCache::DSTOffsetCache()
|
||||
}
|
||||
|
||||
JSContext::JSContext(JSRuntime *rt)
|
||||
: defaultVersion(JSVERSION_DEFAULT),
|
||||
: ContextFriendFields(rt),
|
||||
defaultVersion(JSVERSION_DEFAULT),
|
||||
hasVersionOverride(false),
|
||||
throwing(false),
|
||||
exception(UndefinedValue()),
|
||||
@ -972,12 +973,6 @@ JSContext::JSContext(JSRuntime *rt)
|
||||
localeCallbacks(NULL),
|
||||
resolvingList(NULL),
|
||||
generatingError(false),
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
stackLimit(UINTPTR_MAX),
|
||||
#else
|
||||
stackLimit(0),
|
||||
#endif
|
||||
runtime(rt),
|
||||
compartment(NULL),
|
||||
stack(thisDuringConstruction()), /* depends on cx->thread_ */
|
||||
parseMapPool_(NULL),
|
||||
|
@ -127,9 +127,6 @@ typedef Vector<ScriptOpcodeCountsPair, 0, SystemAllocPolicy> ScriptOpcodeCountsV
|
||||
|
||||
struct ConservativeGCData
|
||||
{
|
||||
/* Base address of the native stack for the current thread. */
|
||||
uintptr_t *nativeStackBase;
|
||||
|
||||
/*
|
||||
* The GC scans conservatively between ThreadData::nativeStackBase and
|
||||
* nativeStackTop unless the latter is NULL.
|
||||
@ -149,7 +146,7 @@ struct ConservativeGCData
|
||||
unsigned requestThreshold;
|
||||
|
||||
ConservativeGCData()
|
||||
: nativeStackBase(NULL), nativeStackTop(NULL), requestThreshold(0)
|
||||
: nativeStackTop(NULL), requestThreshold(0)
|
||||
{}
|
||||
|
||||
~ConservativeGCData() {
|
||||
@ -180,14 +177,8 @@ struct ConservativeGCData
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSRuntime
|
||||
struct JSRuntime : js::RuntimeFriendFields
|
||||
{
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Default compartment. */
|
||||
JSCompartment *atomsCompartment;
|
||||
|
||||
@ -243,6 +234,12 @@ struct JSRuntime
|
||||
return repCache_ ? repCache_ : createRegExpPrivateCache(cx);
|
||||
}
|
||||
|
||||
/* Base address of the native stack for the current thread. */
|
||||
uintptr_t nativeStackBase;
|
||||
|
||||
/* The native stack size limit that runtime should not exceed. */
|
||||
size_t nativeStackQuota;
|
||||
|
||||
/*
|
||||
* Frames currently running in js::Interpret. See InterpreterFrames for
|
||||
* details.
|
||||
@ -428,7 +425,7 @@ struct JSRuntime
|
||||
bool hasContexts() const {
|
||||
return !JS_CLIST_IS_EMPTY(&contextList);
|
||||
}
|
||||
|
||||
|
||||
/* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
|
||||
JSDebugHooks globalDebugHooks;
|
||||
|
||||
@ -764,7 +761,7 @@ typedef HashSet<JSObject *,
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSContext
|
||||
struct JSContext : js::ContextFriendFields
|
||||
{
|
||||
explicit JSContext(JSRuntime *rt);
|
||||
JSContext *thisDuringConstruction() { return this; }
|
||||
@ -800,12 +797,6 @@ struct JSContext
|
||||
*/
|
||||
JSPackedBool generatingError;
|
||||
|
||||
/* Limit pointer for checking native stack consumption during recursion. */
|
||||
uintptr_t stackLimit;
|
||||
|
||||
/* Data shared by contexts and compartments in an address space. */
|
||||
JSRuntime *const runtime;
|
||||
|
||||
/* GC heap compartment. */
|
||||
JSCompartment *compartment;
|
||||
|
||||
|
@ -645,12 +645,6 @@ GetRuntimeCompartments(JSRuntime *rt)
|
||||
return rt->compartments;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uintptr_t)
|
||||
GetContextStackLimit(const JSContext *cx)
|
||||
{
|
||||
return cx->stackLimit;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(size_t)
|
||||
SizeOfJSContext()
|
||||
{
|
||||
|
@ -156,6 +156,42 @@ struct PRLock;
|
||||
|
||||
namespace js {
|
||||
|
||||
struct ContextFriendFields {
|
||||
JSRuntime *const runtime;
|
||||
|
||||
ContextFriendFields(JSRuntime *rt)
|
||||
: runtime(rt) { }
|
||||
|
||||
static const ContextFriendFields *get(const JSContext *cx) {
|
||||
return reinterpret_cast<const ContextFriendFields *>(cx);
|
||||
}
|
||||
};
|
||||
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit;
|
||||
|
||||
RuntimeFriendFields()
|
||||
: interrupt(0),
|
||||
nativeStackLimit(0) { }
|
||||
|
||||
static const RuntimeFriendFields *get(const JSRuntime *rt) {
|
||||
return reinterpret_cast<const RuntimeFriendFields *>(rt);
|
||||
}
|
||||
};
|
||||
|
||||
inline JSRuntime *
|
||||
GetRuntime(const JSContext *cx)
|
||||
{
|
||||
return ContextFriendFields::get(cx)->runtime;
|
||||
}
|
||||
|
||||
typedef bool
|
||||
(* PreserveWrapperCallback)(JSContext *cx, JSObject *obj);
|
||||
|
||||
@ -228,7 +264,7 @@ struct WeakMapTracer {
|
||||
JSContext *context;
|
||||
WeakMapTraceCallback callback;
|
||||
|
||||
WeakMapTracer(JSContext *cx, WeakMapTraceCallback cb)
|
||||
WeakMapTracer(JSContext *cx, WeakMapTraceCallback cb)
|
||||
: context(cx), callback(cb) {}
|
||||
};
|
||||
|
||||
@ -440,8 +476,11 @@ IsObjectInContextCompartment(const JSObject *obj, const JSContext *cx);
|
||||
#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
|
||||
#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
|
||||
|
||||
JS_FRIEND_API(uintptr_t)
|
||||
GetContextStackLimit(const JSContext *cx);
|
||||
inline uintptr_t
|
||||
GetContextStackLimit(const JSContext *cx)
|
||||
{
|
||||
return RuntimeFriendFields::get(GetRuntime(cx))->nativeStackLimit;
|
||||
}
|
||||
|
||||
#define JS_CHECK_RECURSION(cx, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
|
@ -1092,11 +1092,11 @@ MarkConservativeStackRoots(JSTracer *trc, JSRuntime *rt)
|
||||
|
||||
uintptr_t *stackMin, *stackEnd;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
stackMin = rt->conservativeGC.nativeStackBase;
|
||||
stackMin = rt->nativeStackBase;
|
||||
stackEnd = cgcd->nativeStackTop;
|
||||
#else
|
||||
stackMin = cgcd->nativeStackTop + 1;
|
||||
stackEnd = rt->conservativeGC.nativeStackBase;
|
||||
stackEnd = reinterpret_cast<uintptr_t *>(rt->nativeStackBase);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(stackMin <= stackEnd);
|
||||
|
@ -47,12 +47,12 @@ namespace js {
|
||||
extern void *
|
||||
GetNativeStackBaseImpl();
|
||||
|
||||
inline uintptr_t *
|
||||
inline uintptr_t
|
||||
GetNativeStackBase()
|
||||
{
|
||||
void *stackBase = GetNativeStackBaseImpl();
|
||||
JS_ASSERT(reinterpret_cast<uintptr_t>(stackBase) % sizeof(void *) == 0);
|
||||
return static_cast<uintptr_t *>(stackBase);
|
||||
uintptr_t stackBase = reinterpret_cast<uintptr_t>(GetNativeStackBaseImpl());
|
||||
JS_ASSERT(stackBase % sizeof(void *) == 0);
|
||||
return stackBase;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -1332,7 +1332,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn,
|
||||
JSXMLClass xml_class;
|
||||
int stackDummy;
|
||||
|
||||
if (!JS_CHECK_STACK_SIZE(cx->stackLimit, &stackDummy)) {
|
||||
if (!JS_CHECK_STACK_SIZE(cx->runtime->nativeStackLimit, &stackDummy)) {
|
||||
ReportCompileErrorNumber(cx, &parser->tokenStream, pn, JSREPORT_ERROR,
|
||||
JSMSG_OVER_RECURSED);
|
||||
return NULL;
|
||||
|
@ -388,7 +388,6 @@ ShellOperationCallback(JSContext *cx)
|
||||
static void
|
||||
SetContextOptions(JSContext *cx)
|
||||
{
|
||||
JS_SetNativeStackQuota(cx, gMaxStackSize);
|
||||
JS_SetOperationCallback(cx, ShellOperationCallback);
|
||||
}
|
||||
|
||||
@ -5445,6 +5444,8 @@ main(int argc, char **argv, char **envp)
|
||||
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
|
||||
JS_SetRuntimeSecurityCallbacks(rt, &securityCallbacks);
|
||||
|
||||
JS_SetNativeStackQuota(rt, gMaxStackSize);
|
||||
|
||||
if (!InitWatchdog(rt))
|
||||
return 1;
|
||||
|
||||
|
@ -446,9 +446,6 @@ mozJSComponentLoader::ReallyInit()
|
||||
// Always use the latest js version
|
||||
JS_SetVersion(mContext, JSVERSION_LATEST);
|
||||
|
||||
// Limit C stack consumption to a reasonable 512K
|
||||
JS_SetNativeStackQuota(mContext, 512 * 1024);
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secman =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
if (!secman)
|
||||
|
@ -1966,6 +1966,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
// to cause period, and we hope hygienic, last-ditch GCs from within
|
||||
// the GC's allocator.
|
||||
JS_SetGCParameter(mJSRuntime, JSGC_MAX_BYTES, 0xffffffff);
|
||||
JS_SetNativeStackQuota(mJSRuntime, 128 * sizeof(size_t) * 1024);
|
||||
JS_SetContextCallback(mJSRuntime, ContextCallback);
|
||||
JS_SetCompartmentCallback(mJSRuntime, CompartmentCallback);
|
||||
JS_SetGCCallbackRT(mJSRuntime, GCCallback);
|
||||
@ -2090,8 +2091,6 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
|
||||
if (!xpc)
|
||||
return false;
|
||||
|
||||
JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
|
||||
|
||||
// we want to mark the global object ourselves since we use a different color
|
||||
JS_ToggleOptions(cx, JSOPTION_UNROOTED_GLOBAL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user