mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-15 03:00:30 +00:00
bug 453157 - watchdog thread as an alternative to operation count
This commit is contained in:
parent
7c434bc745
commit
4e1445fbdd
@ -109,6 +109,12 @@ else
|
||||
AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_DEBUG), 1)
|
||||
AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=1
|
||||
else
|
||||
AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0
|
||||
endif
|
||||
|
||||
_LEAKTEST_DIR = $(DEPTH)/_leaktest
|
||||
|
||||
_LEAKTEST_FILES = \
|
||||
|
@ -114,6 +114,12 @@ else
|
||||
AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_DEBUG), 1)
|
||||
AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=1
|
||||
else
|
||||
AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0
|
||||
endif
|
||||
|
||||
automation.py: automation.py.in
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
@ -84,6 +84,7 @@ UNIXISH = not IS_WIN32 and not IS_MAC
|
||||
#expand DEFAULT_APP = "./" + __BROWSER_PATH__
|
||||
#expand CERTS_DIR = __CERTS_DIR__
|
||||
#expand IS_TEST_BUILD = __IS_TEST_BUILD__
|
||||
#expand IS_DEBUG_BUILD = __IS_DEBUG_BUILD__
|
||||
|
||||
###########
|
||||
# LOGGING #
|
||||
@ -314,6 +315,13 @@ user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
|
||||
"""
|
||||
prefs.append(part)
|
||||
|
||||
# Increase the max script run time 10-fold for debug builds
|
||||
if (IS_DEBUG_BUILD):
|
||||
prefs.append("""\
|
||||
user_pref("dom.max_script_run_time", 100);
|
||||
user_pref("dom.max_chrome_script_run_time", 200);
|
||||
""")
|
||||
|
||||
locations = readLocations()
|
||||
|
||||
# Grant God-power to all the privileged servers on which tests run.
|
||||
|
@ -852,9 +852,6 @@ 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)
|
||||
{
|
||||
@ -934,24 +931,24 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
||||
|
||||
if (nsContentUtils::GetBoolPref("dom.prevent_oom_dialog", PR_FALSE))
|
||||
return JS_FALSE;
|
||||
|
||||
|
||||
nsCOMPtr<nsIPrompt> prompt = GetPromptFromContext(ctx);
|
||||
|
||||
|
||||
nsXPIDLString title, msg;
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"LowMemoryTitle",
|
||||
title);
|
||||
|
||||
|
||||
rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"LowMemoryMessage",
|
||||
msg);
|
||||
|
||||
|
||||
//GetStringFromName can return NS_OK and still give NULL string
|
||||
if (NS_FAILED(rv) || !title || !msg) {
|
||||
NS_ERROR("Failed to get localized strings.");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
prompt->Alert(title, msg);
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -1238,9 +1235,8 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
|
||||
nsContentUtils::RegisterPrefCallback(js_options_dot_str,
|
||||
JSOptionChangedCallback,
|
||||
this);
|
||||
|
||||
::JS_SetOperationCallback(mContext, DOMOperationCallback,
|
||||
MAYBE_GC_OPERATION_WEIGHT);
|
||||
::JS_SetOperationCallback(mContext, DOMOperationCallback);
|
||||
nsContentUtils::XPConnect()->SetWatchdogLimit(mContext, PR_TicksPerSecond()/10);
|
||||
|
||||
static JSLocaleCallbacks localeCallbacks =
|
||||
{
|
||||
|
@ -794,8 +794,8 @@ nsDOMThreadService::CreateJSContext()
|
||||
|
||||
JS_SetErrorReporter(cx, DOMWorkerErrorReporter);
|
||||
|
||||
JS_SetOperationCallback(cx, DOMWorkerOperationCallback,
|
||||
100 * JS_OPERATION_WEIGHT_BASE);
|
||||
JS_SetOperationCallback(cx, DOMWorkerOperationCallback);
|
||||
nsContentUtils::XPConnect()->SetWatchdogLimit(cx, PR_TicksPerSecond()/100);
|
||||
|
||||
static JSSecurityCallbacks securityCallbacks = {
|
||||
nsDOMWorkerSecurityManager::JSCheckAccess,
|
||||
|
221
js/src/js.cpp
221
js/src/js.cpp
@ -104,10 +104,11 @@ 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;
|
||||
static uint32 gBranchCount;
|
||||
static uint32 gBranchLimit;
|
||||
#endif
|
||||
|
||||
int gExitCode = 0;
|
||||
JSBool gQuitting = JS_FALSE;
|
||||
@ -117,6 +118,18 @@ 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,
|
||||
@ -169,6 +182,7 @@ 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)
|
||||
{
|
||||
@ -197,6 +211,132 @@ 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;
|
||||
if (gWatchdogRunning)
|
||||
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)
|
||||
@ -217,10 +357,12 @@ 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
|
||||
@ -424,7 +566,9 @@ 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':
|
||||
@ -544,6 +688,7 @@ extern void js_InitJITStatsClass(JSContext *cx, JSObject *glob);
|
||||
}
|
||||
break;
|
||||
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
case 'b':
|
||||
if (++i == argc)
|
||||
return usage();
|
||||
@ -551,6 +696,7 @@ extern void js_InitJITStatsClass(JSContext *cx, JSObject *glob);
|
||||
gBranchLimit = atoi(argv[i]);
|
||||
gEnableBranchCallback = (gBranchLimit != 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'c':
|
||||
/* set stack chunk size */
|
||||
@ -2166,6 +2312,38 @@ 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. */
|
||||
@ -2751,12 +2929,14 @@ 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;
|
||||
@ -3056,6 +3236,9 @@ 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),
|
||||
@ -3138,6 +3321,11 @@ 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",
|
||||
@ -3963,7 +4151,14 @@ 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;
|
||||
}
|
||||
|
||||
@ -4011,6 +4206,18 @@ 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);
|
||||
@ -4118,8 +4325,20 @@ 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;
|
||||
}
|
||||
|
@ -905,6 +905,7 @@ JS_BeginRequest(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
JSRuntime *rt;
|
||||
JSContextCallback cxCallback;
|
||||
|
||||
JS_ASSERT(cx->thread->id == js_CurrentThreadId());
|
||||
if (!cx->requestDepth) {
|
||||
@ -912,6 +913,9 @@ 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(). */
|
||||
@ -925,6 +929,16 @@ 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++;
|
||||
@ -985,7 +999,9 @@ 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;
|
||||
}
|
||||
@ -3135,7 +3151,7 @@ DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
attrs, flags, tinyid, NULL);
|
||||
}
|
||||
return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs,
|
||||
NULL);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3812,7 +3828,7 @@ JS_HasUCProperty(JSContext *cx, JSObject *obj,
|
||||
JSProperty *prop;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
ok = LookupUCProperty(cx, obj, name, namelen,
|
||||
ok = LookupUCProperty(cx, obj, name, namelen,
|
||||
JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING,
|
||||
&obj2, &prop);
|
||||
if (ok) {
|
||||
@ -5249,6 +5265,7 @@ 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)
|
||||
@ -5324,7 +5341,34 @@ 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,6 +45,7 @@
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "jsversion.h"
|
||||
#include "js-config.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
@ -2169,6 +2170,13 @@ 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.
|
||||
@ -2193,12 +2201,6 @@ 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)
|
||||
@ -2226,6 +2228,18 @@ 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);
|
||||
|
@ -251,7 +251,11 @@ 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;
|
||||
@ -507,7 +511,7 @@ js_ValidContextPointer(JSRuntime *rt, JSContext *cx)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSContext *
|
||||
JS_FRIEND_API(JSContext *)
|
||||
js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp)
|
||||
{
|
||||
JSContext *cx = *iterp;
|
||||
@ -1348,12 +1352,12 @@ 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;
|
||||
JSStackFrame *fp;
|
||||
|
||||
JS_ASSERT(cx->operationCount <= 0);
|
||||
JS_ASSERT(cx->operationLimit > 0);
|
||||
|
||||
cx->operationCount = (int32) cx->operationLimit;
|
||||
if (cx->operationCallbackIsSet)
|
||||
return cx->operationCallback(cx);
|
||||
@ -1369,6 +1373,14 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -738,8 +738,12 @@ struct JSContext {
|
||||
* Operation count. It is declared as the first field in the struct to
|
||||
* ensure the fastest possible access.
|
||||
*/
|
||||
#if !JS_HAS_OPERATION_COUNT
|
||||
volatile int32 operationCount;
|
||||
#else
|
||||
int32 operationCount;
|
||||
|
||||
#endif
|
||||
|
||||
/* JSRuntime contextList linkage. */
|
||||
JSCList link;
|
||||
|
||||
@ -852,8 +856,10 @@ 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. */
|
||||
@ -879,6 +885,10 @@ 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;
|
||||
|
||||
@ -1058,7 +1068,7 @@ js_ContextFromLinkField(JSCList *link)
|
||||
* If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
|
||||
* the caller must be holding rt->gcLock.
|
||||
*/
|
||||
extern JSContext *
|
||||
extern JS_FRIEND_API(JSContext *)
|
||||
js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
|
||||
|
||||
/*
|
||||
@ -1220,9 +1230,11 @@ extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
||||
* This macro can run the full GC. Return true if it is OK to continue and
|
||||
* false otherwise.
|
||||
*/
|
||||
#define JS_CHECK_OPERATION_LIMIT(cx, weight) \
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
|
||||
# define JS_CHECK_OPERATION_LIMIT(cx, weight) \
|
||||
(JS_CHECK_OPERATION_WEIGHT(weight), \
|
||||
(((cx)->operationCount -= (weight)) > 0 || js_ResetOperationCount(cx)))
|
||||
(((cx)->operationCount -= (weight)) > 0 || js_ResetOperationCount(cx)))
|
||||
|
||||
/*
|
||||
* A version of JS_CHECK_OPERATION_LIMIT that just updates the operation count
|
||||
@ -1230,31 +1242,35 @@ extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
|
||||
* the count to 0 when it becomes negative to prevent a wrap-around when the
|
||||
* macro is called repeatably.
|
||||
*/
|
||||
#define JS_COUNT_OPERATION(cx, weight) \
|
||||
# define JS_COUNT_OPERATION(cx, weight) \
|
||||
((void)(JS_CHECK_OPERATION_WEIGHT(weight), \
|
||||
(cx)->operationCount = ((cx)->operationCount > 0) \
|
||||
? (cx)->operationCount - (weight) \
|
||||
: 0))
|
||||
(cx)->operationCount = ((cx)->operationCount > 0) \
|
||||
? (cx)->operationCount - (weight) \
|
||||
: 0))
|
||||
|
||||
/*
|
||||
* The implementation of the above macros assumes that subtracting weights
|
||||
* twice from a positive number does not wrap-around INT32_MIN.
|
||||
*/
|
||||
#define JS_CHECK_OPERATION_WEIGHT(weight) \
|
||||
# define JS_CHECK_OPERATION_WEIGHT(weight) \
|
||||
(JS_ASSERT((uint32) (weight) > 0), \
|
||||
JS_ASSERT((uint32) (weight) < JS_BIT(30)))
|
||||
|
||||
/* Relative operations weights. */
|
||||
#define JSOW_JUMP 1
|
||||
#define JSOW_ALLOCATION 100
|
||||
#define JSOW_LOOKUP_PROPERTY 5
|
||||
#define JSOW_GET_PROPERTY 10
|
||||
#define JSOW_SET_PROPERTY 20
|
||||
#define JSOW_NEW_PROPERTY 200
|
||||
#define JSOW_DELETE_PROPERTY 30
|
||||
#define JSOW_ENTER_SHARP JS_OPERATION_WEIGHT_BASE
|
||||
#define JSOW_SCRIPT_JUMP JS_OPERATION_WEIGHT_BASE
|
||||
|
||||
# define JSOW_JUMP 1
|
||||
# define JSOW_ALLOCATION 100
|
||||
# define JSOW_LOOKUP_PROPERTY 5
|
||||
# define JSOW_GET_PROPERTY 10
|
||||
# define JSOW_SET_PROPERTY 20
|
||||
# define JSOW_NEW_PROPERTY 200
|
||||
# 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.
|
||||
|
@ -2667,14 +2667,23 @@ js_Interpret(JSContext *cx)
|
||||
* Prepare to call a user-supplied branch handler, and abort the script
|
||||
* if it returns false.
|
||||
*/
|
||||
#define CHECK_BRANCH() \
|
||||
#if JS_HAS_OPERATION_COUNT
|
||||
# define CHECK_BRANCH() \
|
||||
JS_BEGIN_MACRO \
|
||||
if ((cx->operationCount -= JSOW_SCRIPT_JUMP) <= 0) { \
|
||||
if (!js_ResetOperationCount(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; \
|
||||
|
@ -106,8 +106,8 @@ typedef enum JSAccessMode {
|
||||
JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */
|
||||
JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */
|
||||
|
||||
/*
|
||||
* enum value #2 formerly called JSACC_IMPORT,
|
||||
/*
|
||||
* enum value #2 formerly called JSACC_IMPORT,
|
||||
* gap preserved for liveconnect ABI compatibility.
|
||||
*/
|
||||
|
||||
@ -594,21 +594,25 @@ typedef JSBool
|
||||
|
||||
typedef enum JSContextOp {
|
||||
JSCONTEXT_NEW,
|
||||
JSCONTEXT_DESTROY
|
||||
JSCONTEXT_DESTROY,
|
||||
JSCONTEXT_REQUEST_START
|
||||
} JSContextOp;
|
||||
|
||||
/*
|
||||
* The possible values for contextOp when the runtime calls the callback are:
|
||||
* JSCONTEXT_NEW JS_NewContext successfully created a new JSContext
|
||||
* instance. The callback can initialize the instance as
|
||||
* required. If the callback returns false, the instance
|
||||
* will be destroyed and JS_NewContext returns null. In
|
||||
* this case the callback is not called again.
|
||||
* JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The
|
||||
* callback may perform its own cleanup and must always
|
||||
* return true.
|
||||
* Any other value For future compatibility the callback must do nothing
|
||||
* and return true in this case.
|
||||
* JSCONTEXT_NEW JS_NewContext successfully created a new JSContext
|
||||
* instance. The callback can initialize the instance as
|
||||
* required. If the callback returns false, the instance
|
||||
* will be destroyed and JS_NewContext returns null. In
|
||||
* this case the callback is not called again.
|
||||
* 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.
|
||||
*/
|
||||
typedef JSBool
|
||||
(* JSContextCallback)(JSContext *cx, uintN contextOp);
|
||||
|
@ -241,3 +241,11 @@
|
||||
|
||||
/* 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,6 +70,7 @@
|
||||
[ptr] native nsScriptObjectTracerPtr(nsScriptObjectTracer);
|
||||
[ref] native nsCCTraversalCallbackRef(nsCycleCollectionTraversalCallback);
|
||||
[ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
|
||||
native PRIntervalTime(PRIntervalTime);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -405,7 +406,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
||||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(f8bf005e-3700-411c-ba0c-e018075f22a4)]
|
||||
[uuid(eb95710a-e112-44ae-abe1-6f8dfb58d7f8)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
@ -785,4 +786,20 @@ 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);
|
||||
};
|
||||
|
@ -319,13 +319,13 @@ static PRBool NameTester(nsIInterfaceInfoManager* manager, const void* data,
|
||||
*info;
|
||||
}
|
||||
|
||||
static nsresult FindInfo(InfoTester tester, const void* data,
|
||||
static nsresult FindInfo(InfoTester tester, const void* data,
|
||||
nsIInterfaceInfoSuperManager* iism,
|
||||
nsIInterfaceInfo** info)
|
||||
{
|
||||
if(tester(iism, data, info))
|
||||
return NS_OK;
|
||||
|
||||
|
||||
// If not found, then let's ask additional managers.
|
||||
|
||||
PRBool yes;
|
||||
@ -345,9 +345,9 @@ static nsresult FindInfo(InfoTester tester, const void* data,
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXPConnect::GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info)
|
||||
@ -437,7 +437,7 @@ nsXPConnect::Collect()
|
||||
// 1. marking of the roots in category 1 by having the JS GC do its marking
|
||||
// 2. cycle collection
|
||||
// 3. marking of the roots in category 2 by
|
||||
// XPCJSRuntime::TraceXPConnectRoots
|
||||
// XPCJSRuntime::TraceXPConnectRoots
|
||||
// 4. sweeping of unmarked JS objects
|
||||
//
|
||||
// During cycle collection, marked JS objects (and the objects they hold)
|
||||
@ -523,7 +523,7 @@ NoteJSRoot(JSTracer *trc, void *thing, uint32 kind)
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
@ -591,7 +591,7 @@ nsXPConnect::RecordTraversal(void *p, nsISupports *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsXPConnect::FinishCycleCollection()
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
@ -878,7 +878,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
|
||||
if(traceKind != JSTRACE_OBJECT)
|
||||
return NS_OK;
|
||||
|
||||
|
||||
JSObject *obj = static_cast<JSObject*>(p);
|
||||
JSClass* clazz = OBJ_GET_CLASS(cx, obj);
|
||||
|
||||
@ -1708,7 +1708,7 @@ nsXPConnect::GetFunctionThisTranslator(const nsIID & aIID,
|
||||
}
|
||||
|
||||
/* void setSafeJSContextForCurrentThread (in JSContextPtr cx); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::SetSafeJSContextForCurrentThread(JSContext * cx)
|
||||
{
|
||||
XPCCallContext ccx(NATIVE_CALLER);
|
||||
@ -1729,10 +1729,10 @@ nsXPConnect::ClearAllWrappedNativeSecurityPolicies()
|
||||
}
|
||||
|
||||
/* void restoreWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo, in nsIXPConnectJSObjectHolder aPrototype); */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::RestoreWrappedNativePrototype(JSContext * aJSContext,
|
||||
JSObject * aScope,
|
||||
nsIClassInfo * aClassInfo,
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::RestoreWrappedNativePrototype(JSContext * aJSContext,
|
||||
JSObject * aScope,
|
||||
nsIClassInfo * aClassInfo,
|
||||
nsIXPConnectJSObjectHolder * aPrototype)
|
||||
{
|
||||
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
|
||||
@ -1890,10 +1890,10 @@ nsXPConnect::GetXPCWrappedNativeJSClassInfo(const JSClass **clazz,
|
||||
}
|
||||
|
||||
/* nsIXPConnectJSObjectHolder getWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo); */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
|
||||
JSObject * aScope,
|
||||
nsIClassInfo *aClassInfo,
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
|
||||
JSObject * aScope,
|
||||
nsIClassInfo *aClassInfo,
|
||||
nsIXPConnectJSObjectHolder **_retval)
|
||||
{
|
||||
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
|
||||
@ -1909,14 +1909,14 @@ nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
|
||||
XPCWrappedNative::GatherProtoScriptableCreateInfo(aClassInfo, &sciProto);
|
||||
|
||||
AutoMarkingWrappedNativeProtoPtr proto(ccx);
|
||||
proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, scope, aClassInfo,
|
||||
proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, scope, aClassInfo,
|
||||
&sciProto, JS_FALSE,
|
||||
OBJ_IS_NOT_GLOBAL);
|
||||
if(!proto)
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
nsIXPConnectJSObjectHolder* holder;
|
||||
*_retval = holder = XPCJSObjectHolder::newHolder(ccx,
|
||||
*_retval = holder = XPCJSObjectHolder::newHolder(ccx,
|
||||
proto->GetJSProtoObject());
|
||||
if(!holder)
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
@ -1987,7 +1987,7 @@ nsXPConnect::UpdateXOWs(JSContext* aJSContext,
|
||||
}
|
||||
|
||||
/* void releaseJSContext (in JSContextPtr aJSContext, in PRBool noGC); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
|
||||
{
|
||||
NS_ASSERTION(aJSContext, "bad param");
|
||||
@ -1995,8 +1995,8 @@ nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
|
||||
if(tls)
|
||||
{
|
||||
XPCCallContext* ccx = nsnull;
|
||||
for(XPCCallContext* cur = tls->GetCallContext();
|
||||
cur;
|
||||
for(XPCCallContext* cur = tls->GetCallContext();
|
||||
cur;
|
||||
cur = cur->GetPrevCallContext())
|
||||
{
|
||||
if(cur->GetJSContext() == aJSContext)
|
||||
@ -2005,11 +2005,11 @@ nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
|
||||
// Keep looping to find the deepest matching call context.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(ccx)
|
||||
{
|
||||
#ifdef DEBUG_xpc_hacker
|
||||
printf("!xpc - deferring destruction of JSContext @ %p\n",
|
||||
printf("!xpc - deferring destruction of JSContext @ %p\n",
|
||||
(void *)aJSContext);
|
||||
#endif
|
||||
ccx->SetDestroyJSContextInDestructor(JS_TRUE);
|
||||
@ -2018,12 +2018,12 @@ nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
|
||||
}
|
||||
// else continue on and synchronously destroy the JSContext ...
|
||||
|
||||
NS_ASSERTION(!tls->GetJSContextStack() ||
|
||||
NS_ASSERTION(!tls->GetJSContextStack() ||
|
||||
!tls->GetJSContextStack()->
|
||||
DEBUG_StackHasJSContext(aJSContext),
|
||||
"JSContext still in threadjscontextstack!");
|
||||
}
|
||||
|
||||
|
||||
if(noGC)
|
||||
JS_DestroyContextNoGC(aJSContext);
|
||||
else
|
||||
@ -2144,7 +2144,7 @@ nsXPConnect::DebugDumpEvalInJSStackFrame(PRUint32 aFrameNumber, const char *aSou
|
||||
}
|
||||
|
||||
/* JSVal variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, jsval* _retval)
|
||||
{
|
||||
NS_PRECONDITION(ctx, "bad param");
|
||||
@ -2159,7 +2159,7 @@ nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, jsv
|
||||
nsresult rv = NS_OK;
|
||||
if(!XPCVariant::VariantDataToJS(ccx, value, scope, &rv, _retval))
|
||||
{
|
||||
if(NS_FAILED(rv))
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -2169,7 +2169,7 @@ nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, jsv
|
||||
}
|
||||
|
||||
/* nsIVariant JSToVariant (in JSContextPtr ctx, in JSVal value); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::JSToVariant(JSContext* ctx, jsval value, nsIVariant** _retval)
|
||||
{
|
||||
NS_PRECONDITION(ctx, "bad param");
|
||||
@ -2181,7 +2181,7 @@ nsXPConnect::JSToVariant(JSContext* ctx, jsval value, nsIVariant** _retval)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = XPCVariant::newVariant(ccx, value);
|
||||
if(!(*_retval))
|
||||
if(!(*_retval))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
@ -2189,7 +2189,7 @@ nsXPConnect::JSToVariant(JSContext* ctx, jsval value, nsIVariant** _retval)
|
||||
|
||||
/* void flagSystemFilenamePrefix (in string filenamePrefix,
|
||||
* in PRBool aWantNativeWrappers); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::FlagSystemFilenamePrefix(const char *aFilenamePrefix,
|
||||
PRBool aWantNativeWrappers)
|
||||
{
|
||||
@ -2392,6 +2392,18 @@ 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()
|
||||
|
@ -765,7 +765,7 @@ nsXPCComponents_InterfacesByID::CanSetProperty(const nsIID * iid, const PRUnicha
|
||||
|
||||
|
||||
|
||||
class nsXPCComponents_Classes :
|
||||
class nsXPCComponents_Classes :
|
||||
public nsIXPCComponents_Classes,
|
||||
public nsIXPCScriptable,
|
||||
public nsIClassInfo
|
||||
@ -783,9 +783,9 @@ public:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -818,8 +818,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -827,7 +827,7 @@ nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -835,7 +835,7 @@ nsXPCComponents_Classes::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Classes";
|
||||
@ -844,7 +844,7 @@ nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -852,7 +852,7 @@ nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -861,7 +861,7 @@ nsXPCComponents_Classes::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -869,7 +869,7 @@ nsXPCComponents_Classes::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -1038,9 +1038,9 @@ public:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -1073,8 +1073,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -1082,7 +1082,7 @@ nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -1090,7 +1090,7 @@ nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -1099,7 +1099,7 @@ nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -1107,7 +1107,7 @@ nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -1116,7 +1116,7 @@ nsXPCComponents_ClassesByID::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -1124,7 +1124,7 @@ nsXPCComponents_ClassesByID::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -1312,9 +1312,9 @@ public:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -1347,8 +1347,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -1356,7 +1356,7 @@ nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -1364,7 +1364,7 @@ nsXPCComponents_Results::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -1373,7 +1373,7 @@ nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -1381,7 +1381,7 @@ nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -1390,7 +1390,7 @@ nsXPCComponents_Results::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -1398,7 +1398,7 @@ nsXPCComponents_Results::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -1544,9 +1544,9 @@ private:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -1579,8 +1579,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -1588,7 +1588,7 @@ nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -1596,7 +1596,7 @@ nsXPCComponents_ID::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -1605,7 +1605,7 @@ nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -1613,7 +1613,7 @@ nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -1622,7 +1622,7 @@ nsXPCComponents_ID::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -1630,7 +1630,7 @@ nsXPCComponents_ID::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -1771,9 +1771,9 @@ private:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -1806,8 +1806,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -1815,7 +1815,7 @@ nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -1823,7 +1823,7 @@ nsXPCComponents_Exception::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -1832,7 +1832,7 @@ nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -1840,7 +1840,7 @@ nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -1849,7 +1849,7 @@ nsXPCComponents_Exception::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -1857,7 +1857,7 @@ nsXPCComponents_Exception::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -2064,9 +2064,9 @@ private:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -2099,8 +2099,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -2108,7 +2108,7 @@ nsXPCConstructor::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -2116,7 +2116,7 @@ nsXPCConstructor::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -2125,7 +2125,7 @@ nsXPCConstructor::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -2133,7 +2133,7 @@ nsXPCConstructor::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -2142,7 +2142,7 @@ nsXPCConstructor::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -2150,7 +2150,7 @@ nsXPCConstructor::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCConstructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -2329,9 +2329,9 @@ private:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -2364,8 +2364,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -2373,7 +2373,7 @@ nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -2381,7 +2381,7 @@ nsXPCComponents_Constructor::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents_Interfaces";
|
||||
@ -2390,7 +2390,7 @@ nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -2398,7 +2398,7 @@ nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -2407,7 +2407,7 @@ nsXPCComponents_Constructor::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -2415,7 +2415,7 @@ nsXPCComponents_Constructor::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -3220,7 +3220,7 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop)
|
||||
if (!principal || NS_FAILED(rv)) {
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@ -3386,7 +3386,7 @@ public:
|
||||
|
||||
private:
|
||||
static JSBool ContextHolderOperationCallback(JSContext *cx);
|
||||
|
||||
|
||||
XPCAutoJSContext mJSContext;
|
||||
JSContext* mOrigCx;
|
||||
};
|
||||
@ -3405,11 +3405,17 @@ ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox)
|
||||
JS_SetGlobalObject(mJSContext, aSandbox);
|
||||
JS_SetContextPrivate(mJSContext, this);
|
||||
|
||||
if(JS_GetOperationCallback(aOuterCx))
|
||||
PRIntervalTime watchdogLimit =
|
||||
nsXPConnect::GetXPConnect()->GetWatchdogLimit(aOuterCx);
|
||||
|
||||
if(watchdogLimit)
|
||||
{
|
||||
JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback,
|
||||
JS_GetOperationLimit(aOuterCx));
|
||||
JS_SetOperationCallback(mJSContext,
|
||||
ContextHolderOperationCallback);
|
||||
nsXPConnect::GetXPConnect()->SetWatchdogLimit(mJSContext,
|
||||
watchdogLimit);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -3431,7 +3437,9 @@ ContextHolder::ContextHolderOperationCallback(JSContext *cx)
|
||||
{
|
||||
// If the callback is still set in the original context, reflect
|
||||
// a possibly updated operation limit into cx.
|
||||
JS_SetOperationLimit(cx, JS_GetOperationLimit(origCx));
|
||||
PRIntervalTime limit =
|
||||
nsXPConnect::GetXPConnect()->GetWatchdogLimit(origCx);
|
||||
ok = nsXPConnect::GetXPConnect()->SetWatchdogLimit(cx, limit);
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
@ -3736,9 +3744,9 @@ NS_INTERFACE_MAP_END_THREADSAFE
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents)
|
||||
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
|
||||
out nsIIDPtr array); */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
|
||||
{
|
||||
PRUint32 count = 2;
|
||||
@ -3777,8 +3785,8 @@ oom:
|
||||
}
|
||||
|
||||
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetHelperForLanguage(PRUint32 language,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetHelperForLanguage(PRUint32 language,
|
||||
nsISupports **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
@ -3786,7 +3794,7 @@ nsXPCComponents::GetHelperForLanguage(PRUint32 language,
|
||||
}
|
||||
|
||||
/* readonly attribute string contractID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetContractID(char * *aContractID)
|
||||
{
|
||||
*aContractID = nsnull;
|
||||
@ -3794,7 +3802,7 @@ nsXPCComponents::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
/* readonly attribute string classDescription; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
static const char classDescription[] = "XPCComponents";
|
||||
@ -3803,7 +3811,7 @@ nsXPCComponents::GetClassDescription(char * *aClassDescription)
|
||||
}
|
||||
|
||||
/* readonly attribute nsCIDPtr classID; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
*aClassID = nsnull;
|
||||
@ -3811,7 +3819,7 @@ nsXPCComponents::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 implementationLanguage; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetImplementationLanguage(
|
||||
PRUint32 *aImplementationLanguage)
|
||||
{
|
||||
@ -3820,7 +3828,7 @@ nsXPCComponents::GetImplementationLanguage(
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 flags; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::THREADSAFE;
|
||||
@ -3828,7 +3836,7 @@ nsXPCComponents::GetFlags(PRUint32 *aFlags)
|
||||
}
|
||||
|
||||
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -52,6 +52,7 @@ XPCContext::XPCContext(XPCJSRuntime* aRuntime,
|
||||
mPendingResult(NS_OK),
|
||||
mSecurityManager(nsnull),
|
||||
mException(nsnull),
|
||||
mWatchdogLimit(0),
|
||||
mCallingLangType(LANG_UNKNOWN),
|
||||
mSecurityManagerFlags(0)
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ static JSDHashOperator
|
||||
DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
|
||||
uint32 number, void *arg)
|
||||
{
|
||||
XPCWrappedNativeProto* proto =
|
||||
XPCWrappedNativeProto* proto =
|
||||
(XPCWrappedNativeProto*)((JSDHashEntryStub*)hdr)->key;
|
||||
|
||||
proto->Mark();
|
||||
@ -240,6 +240,14 @@ 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;
|
||||
}
|
||||
@ -310,7 +318,7 @@ void XPCJSRuntime::TraceJS(JSTracer* trc, void* data)
|
||||
// them here.
|
||||
for(XPCRootSetElem *e = self->mObjectHolderRoots; e ; e = e->GetNextRoot())
|
||||
static_cast<XPCJSObjectHolder*>(e)->TraceJS(trc);
|
||||
|
||||
|
||||
if(self->GetXPConnect()->ShouldTraceRoots())
|
||||
{
|
||||
// Only trace these if we're not cycle-collecting, the cycle collector
|
||||
@ -482,7 +490,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
||||
case JSGC_MARK_END:
|
||||
{
|
||||
NS_ASSERTION(!self->mDoingFinalization, "bad state");
|
||||
|
||||
|
||||
// mThreadRunningGC indicates that GC is running
|
||||
{ // scoped lock
|
||||
XPCAutoLock lock(self->GetMapLock());
|
||||
@ -505,8 +513,8 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
||||
Enumerate(WrappedJSDyingJSObjectFinder, &data);
|
||||
}
|
||||
|
||||
// Do cleanup in NativeInterfaces. This part just finds
|
||||
// member cloned function objects that are about to be
|
||||
// Do cleanup in NativeInterfaces. This part just finds
|
||||
// member cloned function objects that are about to be
|
||||
// collected. It does not deal with collection of interfaces or
|
||||
// sets at this point.
|
||||
CX_AND_XPCRT_Data data = {cx, self};
|
||||
@ -673,7 +681,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
||||
if(threadLock)
|
||||
{
|
||||
// Do the marking...
|
||||
|
||||
|
||||
{ // scoped lock
|
||||
nsAutoLock lock(threadLock);
|
||||
|
||||
@ -692,7 +700,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
||||
// possibly be valid.
|
||||
if(ccxp->CanGetTearOff())
|
||||
{
|
||||
XPCWrappedNativeTearOff* to =
|
||||
XPCWrappedNativeTearOff* to =
|
||||
ccxp->GetTearOff();
|
||||
if(to)
|
||||
to->Mark();
|
||||
@ -701,7 +709,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do the sweeping...
|
||||
XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs();
|
||||
}
|
||||
@ -777,6 +785,126 @@ 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;
|
||||
if (xpcrt->mWatchdogRunning)
|
||||
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
|
||||
@ -807,7 +935,7 @@ static JSDHashOperator
|
||||
DetachedWrappedNativeProtoShutdownMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
|
||||
uint32 number, void *arg)
|
||||
{
|
||||
XPCWrappedNativeProto* proto =
|
||||
XPCWrappedNativeProto* proto =
|
||||
(XPCWrappedNativeProto*)((JSDHashEntryStub*)hdr)->key;
|
||||
|
||||
proto->SystemIsBeingShutDown((JSContext*)arg);
|
||||
@ -965,6 +1093,12 @@ XPCJSRuntime::~XPCJSRuntime()
|
||||
mJSHolders.ops = nsnull;
|
||||
}
|
||||
|
||||
ShutdownWatchdog();
|
||||
if(mWatchdogWakeup)
|
||||
JS_DESTROY_CONDVAR(mWatchdogWakeup);
|
||||
if(mWatchdogLock)
|
||||
JS_DESTROY_LOCK(mWatchdogLock);
|
||||
|
||||
if(mJSRuntime)
|
||||
{
|
||||
JS_DestroyRuntime(mJSRuntime);
|
||||
@ -998,6 +1132,10 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
mVariantRoots(nsnull),
|
||||
mWrappedJSRoots(nsnull),
|
||||
mObjectHolderRoots(nsnull),
|
||||
mWatchdogLock(nsnull),
|
||||
mWatchdogWakeup(nsnull),
|
||||
mWatchdogThread(nsnull),
|
||||
mCurrentInterval(PR_INTERVAL_NO_TIMEOUT),
|
||||
mUnrootedGlobalCount(0)
|
||||
{
|
||||
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
|
||||
@ -1052,6 +1190,10 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
if(mJSRuntime && !JS_GetGlobalDebugHooks(mJSRuntime)->debuggerHandler)
|
||||
xpc_InstallJSDebuggerKeywordHandler(mJSRuntime);
|
||||
#endif
|
||||
|
||||
mWatchdogLock = JS_NEW_LOCK();
|
||||
if (mWatchdogLock)
|
||||
mWatchdogWakeup = JS_NEW_CONDVAR(mWatchdogLock);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1073,7 +1215,8 @@ XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
self->GetNativeScriptableSharedMap() &&
|
||||
self->GetDyingWrappedNativeProtoMap() &&
|
||||
self->GetExplicitNativeWrapperMap() &&
|
||||
self->GetMapLock())
|
||||
self->GetMapLock() &&
|
||||
self->mWatchdogWakeup)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
@ -1101,7 +1244,7 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
|
||||
mStrJSVals[i] = STRING_TO_JSVAL(str);
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
if(!ok)
|
||||
return JS_FALSE;
|
||||
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
|
||||
@ -1109,7 +1252,7 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
|
||||
return JS_FALSE;
|
||||
|
||||
XPCContext* xpc = new XPCContext(this, cx);
|
||||
if (!xpc)
|
||||
if(!xpc)
|
||||
return JS_FALSE;
|
||||
|
||||
JS_SetThreadStackLimit(cx, tls->GetStackLimit());
|
||||
|
@ -275,22 +275,22 @@ extern const char XPC_XPCONNECT_CONTRACTID[];
|
||||
|
||||
typedef PRMonitor XPCLock;
|
||||
|
||||
static inline void xpc_Wait(XPCLock* lock)
|
||||
static inline void xpc_Wait(XPCLock* lock)
|
||||
{
|
||||
NS_ASSERTION(lock, "xpc_Wait called with null lock!");
|
||||
#ifdef DEBUG
|
||||
PRStatus result =
|
||||
PRStatus result =
|
||||
#endif
|
||||
PR_Wait(lock, PR_INTERVAL_NO_TIMEOUT);
|
||||
NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_Wait!");
|
||||
}
|
||||
|
||||
static inline void xpc_NotifyAll(XPCLock* lock)
|
||||
static inline void xpc_NotifyAll(XPCLock* lock)
|
||||
{
|
||||
NS_ASSERTION(lock, "xpc_NotifyAll called with null lock!");
|
||||
#ifdef DEBUG
|
||||
PRStatus result =
|
||||
#endif
|
||||
PRStatus result =
|
||||
#endif
|
||||
PR_NotifyAll(lock);
|
||||
NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_NotifyAll!");
|
||||
}
|
||||
@ -510,7 +510,7 @@ public:
|
||||
NS_IMETHOD Unroot(void *p);
|
||||
NS_IMETHOD Traverse(void *p,
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
|
||||
// nsCycleCollectionLanguageRuntime
|
||||
virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb);
|
||||
virtual nsresult FinishCycleCollection();
|
||||
@ -736,6 +736,10 @@ 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());
|
||||
@ -757,6 +761,9 @@ 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];
|
||||
@ -783,6 +790,15 @@ private:
|
||||
XPCRootSetElem *mWrappedJSRoots;
|
||||
XPCRootSetElem *mObjectHolderRoots;
|
||||
JSDHashTable mJSHolders;
|
||||
|
||||
/*
|
||||
* Variables to support watchdog thread.
|
||||
*/
|
||||
PRLock *mWatchdogLock;
|
||||
PRCondVar *mWatchdogWakeup;
|
||||
PRBool mWatchdogRunning;
|
||||
PRThread *mWatchdogThread;
|
||||
PRIntervalTime mCurrentInterval;
|
||||
uintN mUnrootedGlobalCount;
|
||||
};
|
||||
|
||||
@ -806,26 +822,26 @@ public:
|
||||
JSContext* GetJSContext() const {return mJSContext;}
|
||||
|
||||
enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
|
||||
|
||||
|
||||
LangType GetCallingLangType() const
|
||||
{
|
||||
return mCallingLangType;
|
||||
}
|
||||
LangType SetCallingLangType(LangType lt)
|
||||
{
|
||||
LangType tmp = mCallingLangType;
|
||||
mCallingLangType = lt;
|
||||
LangType tmp = mCallingLangType;
|
||||
mCallingLangType = lt;
|
||||
return tmp;
|
||||
}
|
||||
JSBool CallerTypeIsJavaScript() const
|
||||
JSBool CallerTypeIsJavaScript() const
|
||||
{
|
||||
return LANG_JS == mCallingLangType;
|
||||
}
|
||||
JSBool CallerTypeIsNative() const
|
||||
JSBool CallerTypeIsNative() const
|
||||
{
|
||||
return LANG_NATIVE == mCallingLangType;
|
||||
}
|
||||
JSBool CallerTypeIsKnown() const
|
||||
JSBool CallerTypeIsKnown() const
|
||||
{
|
||||
return LANG_UNKNOWN != mCallingLangType;
|
||||
}
|
||||
@ -899,6 +915,7 @@ private:
|
||||
nsresult mPendingResult;
|
||||
nsIXPCSecurityManager* mSecurityManager;
|
||||
nsIException* mException;
|
||||
PRIntervalTime mWatchdogLimit;
|
||||
LangType mCallingLangType;
|
||||
PRUint16 mSecurityManagerFlags;
|
||||
|
||||
@ -1242,7 +1259,7 @@ public:
|
||||
{return mScriptObjectPrincipal ?
|
||||
mScriptObjectPrincipal->GetPrincipal() : nsnull;}
|
||||
#endif
|
||||
|
||||
|
||||
JSObject*
|
||||
GetPrototypeJSFunction() const {return mPrototypeJSFunction;}
|
||||
|
||||
@ -1975,7 +1992,7 @@ public:
|
||||
|
||||
// Yes, we *do* need to mark the mScriptableInfo in both cases.
|
||||
void Mark() const
|
||||
{mSet->Mark();
|
||||
{mSet->Mark();
|
||||
if(mScriptableInfo) mScriptableInfo->Mark();}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2497,9 +2514,9 @@ public:
|
||||
JSObject* aJSObj,
|
||||
nsISimpleEnumerator** aEnumerate);
|
||||
|
||||
static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
|
||||
static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
|
||||
JSObject* aJSObj,
|
||||
jsval aName,
|
||||
jsval aName,
|
||||
nsIVariant** aResult);
|
||||
|
||||
virtual ~nsXPCWrappedJSClass();
|
||||
@ -2735,7 +2752,7 @@ public:
|
||||
* @param scope the default scope to put on the new JSObject's __parent__
|
||||
* chain
|
||||
* @param pErr [out] relevant error code, if any.
|
||||
*/
|
||||
*/
|
||||
static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSObject* scope, nsresult* pErr);
|
||||
@ -2771,7 +2788,7 @@ public:
|
||||
|
||||
static JSBool GetNativeInterfaceFromJSObject(XPCCallContext& ccx,
|
||||
void** dest, JSObject* src,
|
||||
const nsID* iid,
|
||||
const nsID* iid,
|
||||
nsresult* pErr);
|
||||
static JSBool JSObject2NativeInterface(XPCCallContext& ccx,
|
||||
void** dest, JSObject* src,
|
||||
@ -2792,7 +2809,7 @@ public:
|
||||
* @param scope the default scope to put on the new JSObjects' __parent__
|
||||
* chain
|
||||
* @param pErr [out] relevant error code, if any.
|
||||
*/
|
||||
*/
|
||||
static JSBool NativeArray2JS(XPCCallContext& ccx,
|
||||
jsval* d, const void** s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
@ -2842,7 +2859,6 @@ public:
|
||||
|
||||
private:
|
||||
XPCConvert(); // not implemented
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -2880,7 +2896,7 @@ public:
|
||||
static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
|
||||
static void ThrowBadParam(nsresult rv, uintN paramNum, XPCCallContext& ccx);
|
||||
#ifdef XPC_IDISPATCH_SUPPORT
|
||||
static void ThrowCOMError(JSContext* cx, unsigned long COMErrorCode,
|
||||
static void ThrowCOMError(JSContext* cx, unsigned long COMErrorCode,
|
||||
nsresult rv = NS_ERROR_XPC_COM_ERROR,
|
||||
const EXCEPINFO * exception = nsnull);
|
||||
#endif
|
||||
@ -3287,7 +3303,7 @@ private:
|
||||
static XPCPerThreadData* gThreads;
|
||||
static PRUintn gTLSIndex;
|
||||
|
||||
// Cached value of cx->thread on the main thread.
|
||||
// Cached value of cx->thread on the main thread.
|
||||
static void *sMainJSThread;
|
||||
|
||||
// Cached per thread data for the main thread. Only safe to access
|
||||
@ -3595,7 +3611,7 @@ private:
|
||||
JSContext *mCX;
|
||||
jsrefcount mDepth;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************/
|
||||
|
||||
@ -3691,7 +3707,7 @@ public:
|
||||
~AutoResolveName()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
jsval old =
|
||||
jsval old =
|
||||
#endif
|
||||
mTLS->SetResolveName(mOld);
|
||||
NS_ASSERTION(old == mCheck, "Bad Nesting!");
|
||||
@ -3717,17 +3733,17 @@ public:
|
||||
}
|
||||
void AutoTrace(JSTracer* trc) {}
|
||||
private:
|
||||
XPCMarkableJSVal(); // not implemented
|
||||
XPCMarkableJSVal(); // not implemented
|
||||
jsval mVal;
|
||||
jsval* mValPtr;
|
||||
};
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
// AutoMarkingPtr is the base class for the various AutoMarking pointer types
|
||||
// below. This system allows us to temporarily protect instances of our garbage
|
||||
// collected types after they are constructed but before they are safely
|
||||
// AutoMarkingPtr is the base class for the various AutoMarking pointer types
|
||||
// below. This system allows us to temporarily protect instances of our garbage
|
||||
// collected types after they are constructed but before they are safely
|
||||
// attached to other rooted objects.
|
||||
// This base class has pure virtual support for marking.
|
||||
// This base class has pure virtual support for marking.
|
||||
|
||||
class AutoMarkingPtr
|
||||
{
|
||||
@ -3736,15 +3752,15 @@ public:
|
||||
: mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
|
||||
|
||||
virtual ~AutoMarkingPtr() {Unlink();}
|
||||
|
||||
void Link()
|
||||
|
||||
void Link()
|
||||
{if(!mTLS) return;
|
||||
AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
|
||||
AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
|
||||
mNext = *list; *list = this;}
|
||||
|
||||
void Unlink()
|
||||
void Unlink()
|
||||
{if(!mTLS) return;
|
||||
AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
|
||||
AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
|
||||
while(*cur != this) {
|
||||
NS_ASSERTION(*cur, "This object not in list!");
|
||||
cur = &(*cur)->mNext;
|
||||
@ -3754,7 +3770,7 @@ public:
|
||||
}
|
||||
|
||||
AutoMarkingPtr* GetNext() {return mNext;}
|
||||
|
||||
|
||||
virtual void TraceJS(JSTracer* trc) = 0;
|
||||
virtual void MarkAfterJSFinalize() = 0;
|
||||
|
||||
@ -3803,7 +3819,7 @@ DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
|
||||
|
||||
|
||||
#define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_) \
|
||||
class class_ : public AutoMarkingPtr \
|
||||
{ \
|
||||
@ -3858,9 +3874,9 @@ protected: \
|
||||
|
||||
DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
|
||||
XPCNativeInterface)
|
||||
|
||||
|
||||
// Note: It looked like I would need one of these AutoMarkingPtr types for
|
||||
// XPCNativeScriptableInfo in order to manage marking its
|
||||
// XPCNativeScriptableInfo in order to manage marking its
|
||||
// XPCNativeScriptableShared member during construction. But AFAICT we build
|
||||
// these and bind them to rooted things so immediately that this just is not
|
||||
// needed.
|
||||
@ -3903,8 +3919,8 @@ public:
|
||||
// the case when mJSVal is JSVAL_STRING, since we don't own the data in
|
||||
// that case.
|
||||
|
||||
// We #define and iid so that out module local code can use QI to detect
|
||||
// if a given nsIVariant is in fact an XPCVariant.
|
||||
// We #define and iid so that out module local code can use QI to detect
|
||||
// if a given nsIVariant is in fact an XPCVariant.
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID)
|
||||
|
||||
static XPCVariant* newVariant(XPCCallContext& ccx, jsval aJSVal);
|
||||
@ -3922,8 +3938,8 @@ public:
|
||||
* chain
|
||||
* @param pErr [out] relevant error code, if any.
|
||||
* @param pJSVal [out] the resulting jsval.
|
||||
*/
|
||||
static JSBool VariantDataToJS(XPCCallContext& ccx,
|
||||
*/
|
||||
static JSBool VariantDataToJS(XPCCallContext& ccx,
|
||||
nsIVariant* variant,
|
||||
JSObject* scope, nsresult* pErr,
|
||||
jsval* pJSVal);
|
||||
|
@ -126,6 +126,12 @@ else
|
||||
TEST_DRIVER_PPARGS += -DIS_TEST_BUILD=0
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_DEBUG), 1)
|
||||
TEST_DRIVER_PPARGS += -DIS_DEBUG_BUILD=1
|
||||
else
|
||||
TEST_DRIVER_PPARGS += -DIS_DEBUG_BUILD=0
|
||||
endif
|
||||
|
||||
runtests.py: runtests.py.in
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
$(TEST_DRIVER_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
|
||||
|
Loading…
Reference in New Issue
Block a user