Redo thread/process stack size checking and API to avoid having to guess/fudge; instead, require embedders to advise explicitly, for fudge-free limits and backward API compatibility (192414, r=shaver).
git-svn-id: svn://10.0.0.236/trunk@147349 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1757,10 +1757,37 @@ JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)
|
||||
return -1;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetStackSizeLimit(JSContext *cx, jsuword stackSizeLimit)
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
CheckStackGrowthDirection(int *dummy1addr, jsuword limitAddr)
|
||||
{
|
||||
js_SetStackSizeLimit(cx, stackSizeLimit);
|
||||
int dummy2;
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
JS_ASSERT(dummy1addr < &dummy2);
|
||||
JS_ASSERT((jsuword)&dummy2 < limitAddr);
|
||||
#else
|
||||
/* Stack grows downward, the common case on modern architectures. */
|
||||
JS_ASSERT(&dummy2 < dummy1addr);
|
||||
JS_ASSERT(limitAddr < (jsuword)&dummy2);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
int dummy1;
|
||||
|
||||
CheckStackGrowthDirection(&dummy1, limitAddr);
|
||||
#endif
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
if (limitAddr == 0)
|
||||
limitAddr = (jsuword)-1;
|
||||
#endif
|
||||
cx->stackLimit = limitAddr;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
@@ -685,12 +685,12 @@ extern JS_PUBLIC_API(intN)
|
||||
JS_GetExternalStringGCType(JSRuntime *rt, JSString *str);
|
||||
|
||||
/*
|
||||
* Sets maximum amount of stack space for the current context that the engine
|
||||
* can use during execution. To disable stack size checking, pass (jsuword)0
|
||||
* for stackSizeLimit.
|
||||
* Sets maximum (if stack grows upward) or minimum (downward) legal stack byte
|
||||
* address in limitAddr for the thread or process stack used by cx. To disable
|
||||
* stack size checking, pass 0 for limitAddr.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetStackSizeLimit(JSContext *cx, jsuword stackSizeLimit);
|
||||
JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||
memset(cx, 0, sizeof *cx);
|
||||
|
||||
cx->runtime = rt;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
cx->stackLimit = (jsuword)-1;
|
||||
#endif
|
||||
#ifdef JS_THREADSAFE
|
||||
js_InitContextForLocking(cx);
|
||||
#endif
|
||||
@@ -145,7 +148,6 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||
JS_UNLOCK_GC(rt);
|
||||
}
|
||||
|
||||
js_SetStackSizeLimit(cx, JS_DEFAULT_STACK_SIZE_LIMIT);
|
||||
return cx;
|
||||
}
|
||||
|
||||
@@ -697,39 +699,3 @@ js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
|
||||
return &js_ErrorFormatString[errorNumber];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
CheckStackGrowthDirection(int *dummy1addr)
|
||||
{
|
||||
int dummy2;
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
JS_ASSERT(&dummy2 > dummy1addr);
|
||||
#else
|
||||
JS_ASSERT(&dummy2 < dummy1addr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
js_SetStackSizeLimit(JSContext *cx, jsuword stackSizeLimit)
|
||||
{
|
||||
int stackDummy;
|
||||
jsuword stackAddr;
|
||||
|
||||
#ifdef DEBUG
|
||||
CheckStackGrowthDirection(&stackDummy);
|
||||
#endif
|
||||
|
||||
stackAddr = (jsuword)&stackDummy;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
cx->stackLimit = (stackAddr + stackSizeLimit > stackAddr)
|
||||
? stackAddr + stackSizeLimit
|
||||
: (jsuword)-1;
|
||||
#else
|
||||
cx->stackLimit = (stackAddr > stackSizeLimit)
|
||||
? stackAddr - stackSizeLimit
|
||||
: 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -470,11 +470,8 @@ js_ReportIsNotDefined(JSContext *cx, const char *name);
|
||||
|
||||
extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
||||
|
||||
extern void
|
||||
js_SetStackSizeLimit(JSContext *cx, jsuword stackSizeLimit);
|
||||
|
||||
/*
|
||||
* See js_SetStackSizeLimit in jscntxt.c, where we assert that the stack grows
|
||||
* See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
|
||||
* in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
|
||||
* computed on the build host by jscpucfg.c and written into jsautocfg.h. The
|
||||
* macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
|
||||
|
||||
@@ -363,9 +363,6 @@ int main(int argc, char **argv)
|
||||
printf("\n");
|
||||
|
||||
printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1));
|
||||
|
||||
/* XXX is there an efficient-to-compute, consistent-across-time limit? */
|
||||
printf("#define JS_DEFAULT_STACK_SIZE_LIMIT %luU\n", (unsigned long)1 << 20);
|
||||
printf("\n");
|
||||
|
||||
printf("#endif /* js_cpucfg___ */\n");
|
||||
|
||||
@@ -192,8 +192,4 @@
|
||||
#define JS_STACK_GROWTH_DIRECTION (-1)
|
||||
#endif
|
||||
|
||||
#ifndef JS_DEFAULT_STACK_SIZE_LIMIT
|
||||
#define JS_DEFAULT_STACK_SIZE_LIMIT JS_BIT(20)
|
||||
#endif
|
||||
|
||||
#endif /* js_cpucfg___ */
|
||||
|
||||
Reference in New Issue
Block a user