зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 1d817f9d842f per beltzner
the windows leak tests were red and osx talos tests were orange
This commit is contained in:
Родитель
3fda62c4d0
Коммит
3fa2a5aa12
|
@ -850,6 +850,9 @@ PrintWinCodebase(nsGlobalWindow *win)
|
|||
}
|
||||
#endif
|
||||
|
||||
// The accumulated operation weight before we call MaybeGC
|
||||
const PRUint32 MAYBE_GC_OPERATION_WEIGHT = 5000 * JS_OPERATION_WEIGHT_BASE;
|
||||
|
||||
static void
|
||||
MaybeGC(JSContext *cx)
|
||||
{
|
||||
|
@ -1233,8 +1236,9 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
|
|||
nsContentUtils::RegisterPrefCallback(js_options_dot_str,
|
||||
JSOptionChangedCallback,
|
||||
this);
|
||||
::JS_SetOperationCallback(mContext, DOMOperationCallback);
|
||||
nsContentUtils::XPConnect()->SetWatchdogLimit(mContext, PR_TicksPerSecond()/10);
|
||||
|
||||
::JS_SetOperationCallback(mContext, DOMOperationCallback,
|
||||
MAYBE_GC_OPERATION_WEIGHT);
|
||||
|
||||
static JSLocaleCallbacks localeCallbacks =
|
||||
{
|
||||
|
|
|
@ -733,8 +733,8 @@ nsDOMThreadService::CreateJSContext()
|
|||
|
||||
JS_SetErrorReporter(cx, DOMWorkerErrorReporter);
|
||||
|
||||
JS_SetOperationCallback(cx, DOMWorkerOperationCallback);
|
||||
nsContentUtils::XPConnect()->SetWatchdogLimit(cx, PR_TicksPerSecond()/100);
|
||||
JS_SetOperationCallback(cx, DOMWorkerOperationCallback,
|
||||
100 * JS_OPERATION_WEIGHT_BASE);
|
||||
|
||||
static JSSecurityCallbacks securityCallbacks = {
|
||||
nsDOMWorkerSecurityManager::JSCheckAccess,
|
||||
|
|
220
js/src/js.cpp
220
js/src/js.cpp
|
@ -104,9 +104,8 @@ static size_t gMaxStackSize = 500000;
|
|||
static jsuword gStackBase;
|
||||
|
||||
static size_t gScriptStackQuota = JS_DEFAULT_SCRIPT_STACK_QUOTA;
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
|
||||
static JSBool gEnableBranchCallback = JS_FALSE;
|
||||
#endif
|
||||
static uint32 gBranchCount;
|
||||
static uint32 gBranchLimit;
|
||||
|
||||
|
@ -118,18 +117,6 @@ FILE *gOutFile = NULL;
|
|||
static JSBool reportWarnings = JS_TRUE;
|
||||
static JSBool compileOnly = JS_FALSE;
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
/*
|
||||
* Variables to support watchdog thread.
|
||||
*/
|
||||
static PRLock *gWatchdogLock;
|
||||
static PRCondVar *gWatchdogWakeup;
|
||||
static PRBool gWatchdogRunning;
|
||||
static PRThread *gWatchdogThread;
|
||||
static PRIntervalTime gCurrentInterval;
|
||||
static PRIntervalTime gWatchdogLimit;
|
||||
#endif
|
||||
|
||||
typedef enum JSShellErrNum {
|
||||
#define MSG_DEF(name, number, count, exception, format) \
|
||||
name = number,
|
||||
|
@ -182,7 +169,6 @@ GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
static JSBool
|
||||
my_BranchCallback(JSContext *cx, JSScript *script)
|
||||
{
|
||||
|
@ -211,131 +197,6 @@ my_BranchCallback(JSContext *cx, JSScript *script)
|
|||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
static void
|
||||
ShutdownWatchdog()
|
||||
{
|
||||
PRThread *t;
|
||||
|
||||
PR_Lock(gWatchdogLock);
|
||||
gWatchdogRunning = PR_FALSE;
|
||||
t = gWatchdogThread;
|
||||
gWatchdogThread = NULL;
|
||||
PR_NotifyCondVar(gWatchdogWakeup);
|
||||
PR_Unlock(gWatchdogLock);
|
||||
if (t)
|
||||
PR_JoinThread(t);
|
||||
}
|
||||
|
||||
static void
|
||||
WakeupWatchdog()
|
||||
{
|
||||
PR_Lock(gWatchdogLock);
|
||||
if (gWatchdogThread && gWatchdogLimit &&
|
||||
(gCurrentInterval == PR_INTERVAL_NO_TIMEOUT ||
|
||||
gCurrentInterval > gWatchdogLimit)) {
|
||||
PR_NotifyCondVar(gWatchdogWakeup);
|
||||
}
|
||||
PR_Unlock(gWatchdogLock);
|
||||
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ShellOperationCallback(JSContext *cx)
|
||||
{
|
||||
if (gWatchdogLimit) {
|
||||
fprintf(stderr, "Error: Script is running too long\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
WatchdogMain(void *arg)
|
||||
{
|
||||
JSRuntime *rt = (JSRuntime *) arg;
|
||||
PRStatus status;
|
||||
PRBool isRunning;
|
||||
|
||||
do {
|
||||
JSContext *iter = NULL;
|
||||
JSContext *acx;
|
||||
JSBool isContextRunning = JS_FALSE;
|
||||
PRIntervalTime ct = PR_IntervalNow();
|
||||
|
||||
PR_Lock(gWatchdogLock);
|
||||
if (gWatchdogLimit) {
|
||||
JS_LOCK_GC(rt);
|
||||
while ((acx = js_ContextIterator(rt, JS_FALSE, &iter))) {
|
||||
if (acx->requestDepth) {
|
||||
if (ct - acx->startTime > gWatchdogLimit)
|
||||
JS_TriggerOperationCallback(acx);
|
||||
if (!isContextRunning)
|
||||
isContextRunning = JS_TRUE;
|
||||
}
|
||||
}
|
||||
JS_UNLOCK_GC(rt);
|
||||
}
|
||||
gCurrentInterval = (isContextRunning && gWatchdogLimit)
|
||||
? gWatchdogLimit
|
||||
: PR_INTERVAL_NO_TIMEOUT;
|
||||
status = PR_WaitCondVar(gWatchdogWakeup, gCurrentInterval);
|
||||
isRunning = gWatchdogRunning;
|
||||
PR_Unlock(gWatchdogLock);
|
||||
} while (isRunning && status == PR_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the watchdog limit associated with the watchdog callback.
|
||||
*/
|
||||
static PRIntervalTime
|
||||
GetWatchdogLimit(JSContext *cx)
|
||||
{
|
||||
return gWatchdogLimit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the watchdog limit associated with the watchdog callback. This API
|
||||
* function may be called only when the result of JS_GetOperationCallback(cx)
|
||||
* is not null.
|
||||
*/
|
||||
static JSBool
|
||||
SetWatchdogLimit(JSContext *cx, PRIntervalTime newWatchdogLimit)
|
||||
{
|
||||
if (newWatchdogLimit == gWatchdogLimit)
|
||||
return JS_TRUE;
|
||||
|
||||
gWatchdogLimit = newWatchdogLimit;
|
||||
|
||||
/*
|
||||
* Start a new watchdog thread if it has not been started. If it has been
|
||||
* started wake up the thread and cause the watchdog rescheduling.
|
||||
*/
|
||||
PR_Lock(gWatchdogLock);
|
||||
if (!gWatchdogThread) {
|
||||
gWatchdogRunning = PR_TRUE;
|
||||
gWatchdogThread =
|
||||
PR_CreateThread(PRThreadType(PR_USER_THREAD),
|
||||
WatchdogMain,
|
||||
cx->runtime,
|
||||
PRThreadPriority(PR_PRIORITY_NORMAL),
|
||||
PRThreadScope(PR_LOCAL_THREAD),
|
||||
PRThreadState(PR_JOINABLE_THREAD),
|
||||
0);
|
||||
}
|
||||
PR_Unlock(gWatchdogLock);
|
||||
if (!gWatchdogThread) {
|
||||
JS_ReportError(cx, "Failed to create watchdog thread");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
WakeupWatchdog();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
SetContextOptions(JSContext *cx)
|
||||
|
@ -356,12 +217,10 @@ SetContextOptions(JSContext *cx)
|
|||
}
|
||||
JS_SetThreadStackLimit(cx, stackLimit);
|
||||
JS_SetScriptStackQuota(cx, gScriptStackQuota);
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
if (gEnableBranchCallback) {
|
||||
JS_SetBranchCallback(cx, my_BranchCallback);
|
||||
JS_ToggleOptions(cx, JSOPTION_NATIVE_BRANCH_CALLBACK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -521,9 +380,7 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
|
|||
break;
|
||||
}
|
||||
switch (argv[i][1]) {
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
case 'b':
|
||||
#endif
|
||||
case 'c':
|
||||
case 'f':
|
||||
case 'e':
|
||||
|
@ -644,12 +501,10 @@ extern void js_InitJITStatsClass(JSContext *cx, JSObject *glob);
|
|||
}
|
||||
break;
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
case 'b':
|
||||
gBranchLimit = atoi(argv[++i]);
|
||||
gEnableBranchCallback = (gBranchLimit != 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'c':
|
||||
/* set stack chunk size */
|
||||
|
@ -2269,38 +2124,6 @@ ThrowError(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
|
||||
static JSBool
|
||||
WatchdogInterval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (argc > 1) {
|
||||
JS_ReportError(cx, "Wrong number of arguments");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (argc == 0)
|
||||
return JS_NewDoubleValue(cx, GetWatchdogLimit(cx), rval);
|
||||
|
||||
jsdouble interval;
|
||||
if (!JS_ValueToNumber(cx, argv[0], &interval))
|
||||
return JS_FALSE;
|
||||
|
||||
/* NB: The next condition take negative values and NaNs into account. */
|
||||
if (!(interval >= 0.0)) {
|
||||
JS_ReportError(cx, "Negative or NaN argument value");
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (interval > 1800.0) {
|
||||
JS_ReportError(cx, "Excessive argument value");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return SetWatchdogLimit(cx, (PRIntervalTime) (interval * PR_TicksPerSecond()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define LAZY_STANDARD_CLASSES
|
||||
|
||||
/* A class for easily testing the inner/outer object callbacks. */
|
||||
|
@ -2861,14 +2684,12 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
|||
JSBool ok;
|
||||
jsrefcount rc;
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
if (!gEnableBranchCallback) {
|
||||
/* Enable the branch callback, for periodic scope-sharing. */
|
||||
gEnableBranchCallback = JS_TRUE;
|
||||
JS_SetBranchCallback(cx, my_BranchCallback);
|
||||
JS_ToggleOptions(cx, JSOPTION_NATIVE_BRANCH_CALLBACK);
|
||||
}
|
||||
#endif
|
||||
|
||||
sd.lock = NULL;
|
||||
sd.cvar = NULL;
|
||||
|
@ -3044,9 +2865,6 @@ static JSFunctionSpec shell_functions[] = {
|
|||
JS_FS("stringsAreUTF8", StringsAreUTF8, 0,0,0),
|
||||
JS_FS("testUTF8", TestUTF8, 1,0,0),
|
||||
JS_FS("throwError", ThrowError, 0,0,0),
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
JS_FS("watchint", WatchdogInterval, 1,0,0),
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
JS_FS("dis", Disassemble, 1,0,0),
|
||||
JS_FS("disfile", DisassFile, 1,0,0),
|
||||
|
@ -3128,11 +2946,6 @@ static const char *const shell_help_messages[] = {
|
|||
"stringsAreUTF8() Check if strings are UTF-8 encoded",
|
||||
"testUTF8(mode) Perform UTF-8 tests (modes are 1 to 4)",
|
||||
"throwError() Throw an error from JS_ReportError",
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
"watchint(interval) Set watchdog interval to the specified number"
|
||||
" of seconds. If parameters are not specified it returns watchdog interval"
|
||||
" in seconds",
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
"dis([fun]) Disassemble functions into bytecodes",
|
||||
"disfile('foo.js') Disassemble script file into bytecodes",
|
||||
|
@ -4074,14 +3887,7 @@ ContextCallback(JSContext *cx, uintN contextOp)
|
|||
JS_SetErrorReporter(cx, my_ErrorReporter);
|
||||
JS_SetVersion(cx, JSVERSION_LATEST);
|
||||
SetContextOptions(cx);
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
JS_SetOperationCallback(cx, ShellOperationCallback);
|
||||
} else if (contextOp == JSCONTEXT_REQUEST_START &&
|
||||
cx->runtime->state != JSRTS_LANDING) {
|
||||
WakeupWatchdog();
|
||||
#endif
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -4128,18 +3934,6 @@ main(int argc, char **argv, char **envp)
|
|||
rt = JS_NewRuntime(64L * 1024L * 1024L);
|
||||
if (!rt)
|
||||
return 1;
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
gWatchdogLock = JS_NEW_LOCK();
|
||||
if (!gWatchdogLock)
|
||||
return 1;
|
||||
gWatchdogWakeup = JS_NEW_CONDVAR(gWatchdogLock);
|
||||
if (!gWatchdogWakeup)
|
||||
return 1;
|
||||
gWatchdogLimit = 0;
|
||||
gWatchdogThread = NULL;
|
||||
#endif
|
||||
|
||||
JS_SetContextCallback(rt, ContextCallback);
|
||||
|
||||
cx = JS_NewContext(rt, gStackChunkSize);
|
||||
|
@ -4249,20 +4043,8 @@ main(int argc, char **argv, char **envp)
|
|||
JS_EndRequest(cx);
|
||||
#endif
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
ShutdownWatchdog();
|
||||
#endif
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
if (gWatchdogWakeup)
|
||||
JS_DESTROY_CONDVAR(gWatchdogWakeup);
|
||||
if (gWatchdogLock)
|
||||
JS_DESTROY_LOCK(gWatchdogLock);
|
||||
#endif
|
||||
|
||||
JS_DestroyContext(cx);
|
||||
JS_DestroyRuntime(rt);
|
||||
JS_ShutDown();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -903,7 +903,6 @@ JS_BeginRequest(JSContext *cx)
|
|||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JSRuntime *rt;
|
||||
JSContextCallback cxCallback;
|
||||
|
||||
JS_ASSERT(cx->thread->id == js_CurrentThreadId());
|
||||
if (!cx->requestDepth) {
|
||||
|
@ -911,9 +910,6 @@ JS_BeginRequest(JSContext *cx)
|
|||
|
||||
/* Wait until the GC is finished. */
|
||||
rt = cx->runtime;
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
cx->startTime = PR_IntervalNow();
|
||||
#endif
|
||||
JS_LOCK_GC(rt);
|
||||
|
||||
/* NB: we use cx->thread here, not js_GetCurrentThread(). */
|
||||
|
@ -927,16 +923,6 @@ JS_BeginRequest(JSContext *cx)
|
|||
cx->requestDepth = 1;
|
||||
cx->outstandingRequests++;
|
||||
JS_UNLOCK_GC(rt);
|
||||
|
||||
cxCallback = cx->runtime->cxCallback;
|
||||
if (cxCallback) {
|
||||
#ifdef DEBUG
|
||||
JSBool callbackStatus =
|
||||
#endif
|
||||
cxCallback(cx, JSCONTEXT_REQUEST_START);
|
||||
JS_ASSERT(callbackStatus);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
cx->requestDepth++;
|
||||
|
@ -997,9 +983,7 @@ JS_EndRequest(JSContext *cx)
|
|||
rt->requestCount--;
|
||||
if (rt->requestCount == 0)
|
||||
JS_NOTIFY_REQUEST_DONE(rt);
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
cx->startTime = 0;
|
||||
#endif
|
||||
|
||||
JS_UNLOCK_GC(rt);
|
||||
return;
|
||||
}
|
||||
|
@ -5260,7 +5244,6 @@ JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
|
|||
return ok;
|
||||
}
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback,
|
||||
uint32 operationLimit)
|
||||
|
@ -5336,33 +5319,6 @@ JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb)
|
|||
}
|
||||
return oldcb;
|
||||
}
|
||||
#else
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback)
|
||||
{
|
||||
cx->operationCallback = callback;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearOperationCallback(JSContext *cx)
|
||||
{
|
||||
cx->operationCallback = NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSOperationCallback)
|
||||
JS_GetOperationCallback(JSContext *cx)
|
||||
{
|
||||
return cx->operationCallback;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_TriggerOperationCallback(JSContext *cx)
|
||||
{
|
||||
cx->operationCount = 0;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsRunning(JSContext *cx)
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "jsversion.h"
|
||||
#include "js-config.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
|
@ -2167,13 +2166,6 @@ extern JS_PUBLIC_API(JSBool)
|
|||
JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
|
||||
jsval *argv, jsval *rval);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearOperationCallback(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(JSOperationCallback)
|
||||
JS_GetOperationCallback(JSContext *cx);
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
/*
|
||||
* The maximum value of the operation limit to pass to JS_SetOperationCallback
|
||||
* and JS_SetOperationLimit.
|
||||
|
@ -2198,6 +2190,12 @@ extern JS_PUBLIC_API(void)
|
|||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback,
|
||||
uint32 operationLimit);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearOperationCallback(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(JSOperationCallback)
|
||||
JS_GetOperationCallback(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Get the operation limit associated with the operation callback. This API
|
||||
* function may be called only when the result of JS_GetOperationCallback(cx)
|
||||
|
@ -2225,18 +2223,6 @@ JS_SetOperationLimit(JSContext *cx, uint32 operationLimit);
|
|||
*/
|
||||
extern JS_PUBLIC_API(JSBranchCallback)
|
||||
JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb);
|
||||
#else
|
||||
/*
|
||||
* Set the operation callback that the engine calls while resetting
|
||||
* context.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback);
|
||||
|
||||
#endif
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_TriggerOperationCallback(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_IsRunning(JSContext *cx);
|
||||
|
|
|
@ -241,11 +241,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
|||
memset(cx, 0, sizeof *cx);
|
||||
|
||||
cx->runtime = rt;
|
||||
#if JS_OPERATION_COUNT
|
||||
JS_ClearOperationCallback(cx);
|
||||
#else
|
||||
cx->operationCount = 1;
|
||||
#endif
|
||||
cx->debugHooks = &rt->globalDebugHooks;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
cx->stackLimit = (jsuword)-1;
|
||||
|
@ -520,7 +516,7 @@ js_ValidContextPointer(JSRuntime *rt, JSContext *cx)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSContext *)
|
||||
JSContext *
|
||||
js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp)
|
||||
{
|
||||
JSContext *cx = *iterp;
|
||||
|
@ -1375,11 +1371,9 @@ js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
|
|||
JSBool
|
||||
js_ResetOperationCount(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(cx->operationCount <= 0);
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
JSScript *script;
|
||||
|
||||
JS_ASSERT(cx->operationCount <= 0);
|
||||
JS_ASSERT(cx->operationLimit > 0);
|
||||
|
||||
cx->operationCount = (int32) cx->operationLimit;
|
||||
|
@ -1396,13 +1390,5 @@ js_ResetOperationCount(JSContext *cx)
|
|||
if (script || JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK))
|
||||
return ((JSBranchCallback) cx->operationCallback)(cx, script);
|
||||
}
|
||||
#else
|
||||
JSOperationCallback operationCallback;
|
||||
|
||||
cx->operationCount = 1;
|
||||
operationCallback = cx->operationCallback;
|
||||
if (operationCallback)
|
||||
return operationCallback(cx);
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -739,11 +739,7 @@ struct JSContext {
|
|||
* Operation count. It is declared early in the structure as a frequently
|
||||
* accessed field.
|
||||
*/
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
volatile int32 operationCount;
|
||||
#else
|
||||
int32 operationCount;
|
||||
#endif
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
/*
|
||||
|
@ -852,10 +848,8 @@ struct JSContext {
|
|||
* but operationCallback is not null, operationCallback stores the branch
|
||||
* callback.
|
||||
*/
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
uint32 operationCallbackIsSet : 1;
|
||||
uint32 operationLimit : 31;
|
||||
#endif
|
||||
JSOperationCallback operationCallback;
|
||||
|
||||
/* Interpreter activation count. */
|
||||
|
@ -881,10 +875,6 @@ struct JSContext {
|
|||
((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
|
||||
#endif
|
||||
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
PRIntervalTime startTime; /* time when the context thread was started */
|
||||
#endif
|
||||
|
||||
/* PDL of stack headers describing stack slots not rooted by argv, etc. */
|
||||
JSStackHeader *stackHeaders;
|
||||
|
||||
|
@ -1048,7 +1038,7 @@ js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
|
|||
* If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
|
||||
* the caller must be holding rt->gcLock.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSContext *)
|
||||
extern JSContext *
|
||||
js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
|
||||
|
||||
/*
|
||||
|
@ -1210,8 +1200,6 @@ extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
|||
* This macro can run the full GC. Return true if it is OK to continue and
|
||||
* false otherwise.
|
||||
*/
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
|
||||
#define JS_CHECK_OPERATION_LIMIT(cx, weight) \
|
||||
(JS_CHECK_OPERATION_WEIGHT(weight), \
|
||||
(((cx)->operationCount -= (weight)) > 0 || js_ResetOperationCount(cx)))
|
||||
|
@ -1246,11 +1234,7 @@ extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
|||
#define JSOW_DELETE_PROPERTY 30
|
||||
#define JSOW_ENTER_SHARP JS_OPERATION_WEIGHT_BASE
|
||||
#define JSOW_SCRIPT_JUMP JS_OPERATION_WEIGHT_BASE
|
||||
#else
|
||||
# define JS_CHECK_OPERATION_LIMIT(cx, weight) \
|
||||
(((cx)->operationCount) > 0 || js_ResetOperationCount(cx))
|
||||
# define JS_COUNT_OPERATION(cx, weight) ((void) 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reset the operation count and call the operation callback assuming that the
|
||||
* operation limit is reached.
|
||||
|
|
|
@ -2665,7 +2665,6 @@ js_Interpret(JSContext *cx)
|
|||
* Prepare to call a user-supplied branch handler, and abort the script
|
||||
* if it returns false.
|
||||
*/
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
#define CHECK_BRANCH() \
|
||||
JS_BEGIN_MACRO \
|
||||
if ((cx->operationCount -= JSOW_SCRIPT_JUMP) <= 0) { \
|
||||
|
@ -2673,15 +2672,7 @@ js_Interpret(JSContext *cx)
|
|||
goto error; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
# define CHECK_BRANCH() \
|
||||
JS_BEGIN_MACRO \
|
||||
if (cx->operationCount < 1) { \
|
||||
if (!js_ResetOperationCount(cx)) \
|
||||
goto error; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
#define BRANCH(n) \
|
||||
JS_BEGIN_MACRO \
|
||||
regs.pc += n; \
|
||||
|
|
|
@ -594,8 +594,7 @@ typedef JSBool
|
|||
|
||||
typedef enum JSContextOp {
|
||||
JSCONTEXT_NEW,
|
||||
JSCONTEXT_DESTROY,
|
||||
JSCONTEXT_REQUEST_START
|
||||
JSCONTEXT_DESTROY
|
||||
} JSContextOp;
|
||||
|
||||
/*
|
||||
|
@ -608,9 +607,6 @@ typedef enum JSContextOp {
|
|||
* JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The
|
||||
* callback may perform its own cleanup and must always
|
||||
* return true.
|
||||
* JSCONTEXT_REQUEST_START JS_BeginRequest was called with requestDepth == 0.
|
||||
* This callback can be used to notify other components
|
||||
* that execution has begun on this context.
|
||||
* Any other value For future compatibility the callback must do nothing
|
||||
* and return true in this case.
|
||||
*/
|
||||
|
|
|
@ -241,11 +241,3 @@
|
|||
|
||||
/* Feature-test macro for evolving destructuring support. */
|
||||
#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2)
|
||||
|
||||
#ifndef JS_HAS_OPERATION_COUNT
|
||||
# if defined(MOZILLA_VERSION) || defined(JS_THREADSAFE)
|
||||
# define JS_HAS_OPERATION_COUNT 0
|
||||
# else
|
||||
# define JS_HAS_OPERATION_COUNT 1
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
[ptr] native nsScriptObjectTracerPtr(nsScriptObjectTracer);
|
||||
[ref] native nsCCTraversalCallbackRef(nsCycleCollectionTraversalCallback);
|
||||
[ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
|
||||
native PRIntervalTime(PRIntervalTime);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -406,7 +405,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
|||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(eb95710a-e112-44ae-abe1-6f8dfb58d7f8)]
|
||||
[uuid(d4c6bc06-2a4f-4315-90ec-d12904aca046)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
|
@ -768,20 +767,4 @@ interface nsIXPConnect : nsISupports
|
|||
in PRUint32 flags,
|
||||
in PRUint32 interfaceCount,
|
||||
[array, size_is(interfaceCount)] in nsIIDPtr interfaceArray);
|
||||
|
||||
/**
|
||||
* Returns the value of the watchdog limit for the specified context.
|
||||
* @param cx
|
||||
* A context
|
||||
*/
|
||||
[noscript,notxpcom] PRIntervalTime getWatchdogLimit(in JSContextPtr cx);
|
||||
|
||||
/**
|
||||
* Sets a new value of the watchdog limit.
|
||||
* @param cx
|
||||
* A context
|
||||
* @param limit
|
||||
* New value of the watchdog limit.
|
||||
*/
|
||||
[noscript,notxpcom] PRBool setWatchdogLimit(in JSContextPtr cx, in PRIntervalTime limit);
|
||||
};
|
||||
|
|
|
@ -2376,18 +2376,6 @@ nsXPConnect::SetSafeJSContext(JSContext * aSafeJSContext)
|
|||
return data->GetJSContextStack()->SetSafeJSContext(aSafeJSContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsXPConnect::SetWatchdogLimit(JSContext *cx, PRIntervalTime limit)
|
||||
{
|
||||
return GetRuntime()->SetWatchdogLimit(cx, limit);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRIntervalTime)
|
||||
nsXPConnect::GetWatchdogLimit(JSContext *cx)
|
||||
{
|
||||
return GetRuntime()->GetWatchdogLimit(cx);
|
||||
}
|
||||
|
||||
/* These are here to be callable from a debugger */
|
||||
JS_BEGIN_EXTERN_C
|
||||
JS_EXPORT_API(void) DumpJSStack()
|
||||
|
|
|
@ -3405,17 +3405,11 @@ ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox)
|
|||
JS_SetGlobalObject(mJSContext, aSandbox);
|
||||
JS_SetContextPrivate(mJSContext, this);
|
||||
|
||||
PRIntervalTime watchdogLimit =
|
||||
nsXPConnect::GetXPConnect()->GetWatchdogLimit(aOuterCx);
|
||||
|
||||
if(watchdogLimit)
|
||||
if(JS_GetOperationCallback(aOuterCx))
|
||||
{
|
||||
JS_SetOperationCallback(mJSContext,
|
||||
ContextHolderOperationCallback);
|
||||
nsXPConnect::GetXPConnect()->SetWatchdogLimit(mJSContext,
|
||||
watchdogLimit);
|
||||
JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback,
|
||||
JS_GetOperationLimit(aOuterCx));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3437,9 +3431,7 @@ ContextHolder::ContextHolderOperationCallback(JSContext *cx)
|
|||
{
|
||||
// If the callback is still set in the original context, reflect
|
||||
// a possibly updated operation limit into cx.
|
||||
PRIntervalTime limit =
|
||||
nsXPConnect::GetXPConnect()->GetWatchdogLimit(origCx);
|
||||
ok = nsXPConnect::GetXPConnect()->SetWatchdogLimit(cx, limit);
|
||||
JS_SetOperationLimit(cx, JS_GetOperationLimit(origCx));
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ XPCContext::XPCContext(XPCJSRuntime* aRuntime,
|
|||
mPendingResult(NS_OK),
|
||||
mSecurityManager(nsnull),
|
||||
mException(nsnull),
|
||||
mWatchdogLimit(0),
|
||||
mCallingLangType(LANG_UNKNOWN),
|
||||
mSecurityManagerFlags(0)
|
||||
{
|
||||
|
|
|
@ -239,14 +239,6 @@ ContextCallback(JSContext *cx, uintN operation)
|
|||
{
|
||||
delete XPCContext::GetXPCContext(cx);
|
||||
}
|
||||
else if(operation == JSCONTEXT_REQUEST_START)
|
||||
{
|
||||
// If we're called during context creation, we will assert if we
|
||||
// try to call XPCContext::GetXPCContext.
|
||||
if(!cx->data2)
|
||||
return JS_TRUE;
|
||||
self->WakeupWatchdog(cx);
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -828,124 +820,6 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
XPCJSRuntime::WatchdogMain(void *arg)
|
||||
{
|
||||
XPCJSRuntime *xpcrt = (XPCJSRuntime *) arg;
|
||||
JSRuntime *rt = xpcrt->GetJSRuntime();
|
||||
PRStatus status;
|
||||
PRBool isRunning;
|
||||
|
||||
do
|
||||
{
|
||||
JSContext *iter = NULL;
|
||||
JSContext *acx;
|
||||
PRIntervalTime newInterval = (PRIntervalTime) 0;
|
||||
XPCContext *ccx;
|
||||
|
||||
PRIntervalTime ct = PR_IntervalNow();
|
||||
PR_Lock(xpcrt->mWatchdogLock);
|
||||
JS_LOCK_GC(rt);
|
||||
|
||||
while((acx = js_ContextIterator(rt, JS_FALSE, &iter)))
|
||||
{
|
||||
if(acx->requestDepth)
|
||||
{
|
||||
ccx = XPCContext::GetXPCContext(acx);
|
||||
if(ccx->mWatchdogLimit &&
|
||||
ct - acx->startTime > ccx->mWatchdogLimit)
|
||||
{
|
||||
JS_TriggerOperationCallback(acx);
|
||||
}
|
||||
if(newInterval > ccx->mWatchdogLimit || !newInterval)
|
||||
newInterval = ccx->mWatchdogLimit;
|
||||
}
|
||||
}
|
||||
JS_UNLOCK_GC(rt);
|
||||
|
||||
xpcrt->mCurrentInterval = newInterval ? newInterval
|
||||
: PR_INTERVAL_NO_TIMEOUT;
|
||||
status = PR_WaitCondVar(xpcrt->mWatchdogWakeup, xpcrt->mCurrentInterval);
|
||||
isRunning = xpcrt->mWatchdogRunning;
|
||||
PR_Unlock(xpcrt->mWatchdogLock);
|
||||
} while (isRunning && status == PR_SUCCESS);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPCJSRuntime::SetWatchdogLimit(JSContext *cx, PRIntervalTime newWatchdogLimit)
|
||||
{
|
||||
PRBool isRunning;
|
||||
PRIntervalTime oldWatchdogLimit;
|
||||
XPCContext *ccx = XPCContext::GetXPCContext(cx);
|
||||
|
||||
if(newWatchdogLimit == ccx->mWatchdogLimit)
|
||||
return PR_TRUE;
|
||||
|
||||
oldWatchdogLimit = ccx->mWatchdogLimit;
|
||||
ccx->mWatchdogLimit = newWatchdogLimit;
|
||||
|
||||
/*
|
||||
* Start a new watchdog thread if it has not been started. If it has been
|
||||
* started wake up the thread and cause the watchdog rescheduling.
|
||||
*/
|
||||
PR_Lock(mWatchdogLock);
|
||||
isRunning = !!mWatchdogThread;
|
||||
|
||||
if(!isRunning)
|
||||
{
|
||||
mWatchdogRunning = PR_TRUE;
|
||||
mWatchdogThread =
|
||||
PR_CreateThread(PRThreadType(PR_USER_THREAD),
|
||||
WatchdogMain,
|
||||
this,
|
||||
PRThreadPriority(PR_PRIORITY_NORMAL),
|
||||
PRThreadScope(PR_LOCAL_THREAD),
|
||||
PRThreadState(PR_JOINABLE_THREAD),
|
||||
0);
|
||||
}
|
||||
PR_Unlock(mWatchdogLock);
|
||||
if(!mWatchdogThread)
|
||||
return PR_FALSE;
|
||||
if(isRunning &&
|
||||
(oldWatchdogLimit > ccx->mWatchdogLimit ||
|
||||
mCurrentInterval == PR_INTERVAL_NO_TIMEOUT))
|
||||
WakeupWatchdog(cx);
|
||||
return PR_TRUE;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
XPCJSRuntime::WakeupWatchdog(JSContext *cx)
|
||||
{
|
||||
XPCContext *ccx = XPCContext::GetXPCContext(cx);
|
||||
PR_Lock(mWatchdogLock);
|
||||
if(mCurrentInterval == PR_INTERVAL_NO_TIMEOUT ||
|
||||
(ccx && mCurrentInterval > ccx->mWatchdogLimit))
|
||||
PR_NotifyCondVar(mWatchdogWakeup);
|
||||
PR_Unlock(mWatchdogLock);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPCJSRuntime::ShutdownWatchdog()
|
||||
{
|
||||
PR_Lock(mWatchdogLock);
|
||||
mWatchdogRunning = PR_FALSE;
|
||||
PRThread *t = mWatchdogThread;
|
||||
mWatchdogThread = NULL;
|
||||
PR_NotifyCondVar(mWatchdogWakeup);
|
||||
PR_Unlock(mWatchdogLock);
|
||||
if(t)
|
||||
PR_JoinThread(t);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRIntervalTime
|
||||
XPCJSRuntime::GetWatchdogLimit(JSContext *cx)
|
||||
{
|
||||
return XPCContext::GetXPCContext(cx)->mWatchdogLimit;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
|
||||
|
@ -1137,12 +1011,6 @@ XPCJSRuntime::~XPCJSRuntime()
|
|||
mClearedGlobalObjects.ops = nsnull;
|
||||
}
|
||||
|
||||
ShutdownWatchdog();
|
||||
if(mWatchdogWakeup)
|
||||
JS_DESTROY_CONDVAR(mWatchdogWakeup);
|
||||
if(mWatchdogLock)
|
||||
JS_DESTROY_LOCK(mWatchdogLock);
|
||||
|
||||
if(mJSRuntime)
|
||||
{
|
||||
JS_DestroyRuntime(mJSRuntime);
|
||||
|
@ -1230,11 +1098,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
|||
if(mJSRuntime && !JS_GetGlobalDebugHooks(mJSRuntime)->debuggerHandler)
|
||||
xpc_InstallJSDebuggerKeywordHandler(mJSRuntime);
|
||||
#endif
|
||||
|
||||
mWatchdogLock = JS_NEW_LOCK();
|
||||
mWatchdogWakeup = JS_NEW_CONDVAR(mWatchdogLock);
|
||||
mWatchdogThread = NULL;
|
||||
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -738,10 +738,6 @@ public:
|
|||
|
||||
~XPCJSRuntime();
|
||||
|
||||
PRIntervalTime GetWatchdogLimit(JSContext *cx);
|
||||
PRBool SetWatchdogLimit(JSContext *cx, PRIntervalTime limit);
|
||||
void WakeupWatchdog(JSContext *cx);
|
||||
|
||||
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
|
||||
void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
|
||||
{XPCAutoLock lock(GetMapLock());
|
||||
|
@ -763,9 +759,6 @@ private:
|
|||
XPCJSRuntime(); // no implementation
|
||||
XPCJSRuntime(nsXPConnect* aXPConnect);
|
||||
|
||||
PRBool ShutdownWatchdog();
|
||||
static void WatchdogMain(void *args);
|
||||
|
||||
private:
|
||||
static const char* mStrings[IDX_TOTAL_COUNT];
|
||||
jsid mStrIDs[IDX_TOTAL_COUNT];
|
||||
|
@ -793,15 +786,6 @@ private:
|
|||
XPCRootSetElem *mObjectHolderRoots;
|
||||
JSDHashTable mJSHolders;
|
||||
JSDHashTable mClearedGlobalObjects;
|
||||
|
||||
/*
|
||||
* Variables to support watchdog thread.
|
||||
*/
|
||||
PRLock *mWatchdogLock;
|
||||
PRCondVar *mWatchdogWakeup;
|
||||
PRBool mWatchdogRunning;
|
||||
PRThread *mWatchdogThread;
|
||||
PRIntervalTime mCurrentInterval;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -917,7 +901,6 @@ private:
|
|||
nsresult mPendingResult;
|
||||
nsIXPCSecurityManager* mSecurityManager;
|
||||
nsIException* mException;
|
||||
PRIntervalTime mWatchdogLimit;
|
||||
LangType mCallingLangType;
|
||||
PRUint16 mSecurityManagerFlags;
|
||||
|
||||
|
@ -2859,6 +2842,7 @@ public:
|
|||
|
||||
private:
|
||||
XPCConvert(); // not implemented
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
Загрузка…
Ссылка в новой задаче