mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 845545: Part 2 - Refactor context creation callbacks. r=bholley,mccr8
This commit is contained in:
parent
b09945aa3b
commit
147c3dee65
@ -854,14 +854,11 @@ JS_IsInRequest(JSRuntime *rt)
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSContextCallback)
|
||||
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback, void *data)
|
||||
{
|
||||
JSContextCallback old;
|
||||
|
||||
old = rt->cxCallback;
|
||||
rt->cxCallback = cxCallback;
|
||||
return old;
|
||||
rt->cxCallbackData = data;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSContext *)
|
||||
|
@ -965,7 +965,7 @@ typedef enum JSContextOp {
|
||||
* and return true in this case.
|
||||
*/
|
||||
typedef JSBool
|
||||
(* JSContextCallback)(JSContext *cx, unsigned contextOp);
|
||||
(* JSContextCallback)(JSContext *cx, unsigned contextOp, void *data);
|
||||
|
||||
typedef enum JSGCStatus {
|
||||
JSGC_BEGIN,
|
||||
@ -1909,8 +1909,8 @@ class JSAutoCheckRequest
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(JSContextCallback)
|
||||
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback, void *data);
|
||||
|
||||
extern JS_PUBLIC_API(JSContext *)
|
||||
JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
|
||||
|
@ -211,7 +211,7 @@ js::NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||
}
|
||||
|
||||
JSContextCallback cxCallback = rt->cxCallback;
|
||||
if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
|
||||
if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW, rt->cxCallbackData)) {
|
||||
DestroyContext(cx, DCM_NEW_FAILED);
|
||||
return NULL;
|
||||
}
|
||||
@ -241,7 +241,8 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
|
||||
* JSCONTEXT_DESTROY callback is not allowed to fail and must
|
||||
* return true.
|
||||
*/
|
||||
JS_ALWAYS_TRUE(cxCallback(cx, JSCONTEXT_DESTROY));
|
||||
JS_ALWAYS_TRUE(cxCallback(cx, JSCONTEXT_DESTROY,
|
||||
rt->cxCallbackData));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,6 +923,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
|
||||
/* Context create/destroy callback. */
|
||||
JSContextCallback cxCallback;
|
||||
void *cxCallbackData;
|
||||
|
||||
/* Compartment destroy callback. */
|
||||
JSDestroyCompartmentCallback destroyCompartmentCallback;
|
||||
|
@ -7,18 +7,23 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[ptr] native JSRuntime(JSRuntime);
|
||||
[ptr] native JSContext(JSContext);
|
||||
native xpcGCCallback(xpcGCCallback);
|
||||
native xpcContextCallback(xpcContextCallback);
|
||||
|
||||
%{C++
|
||||
|
||||
typedef void
|
||||
(* xpcGCCallback)(JSGCStatus status);
|
||||
|
||||
typedef bool
|
||||
(* xpcContextCallback)(JSContext* cx, unsigned operation);
|
||||
|
||||
%}
|
||||
|
||||
interface nsIBackstagePass;
|
||||
|
||||
[uuid(996ef894-88cd-42c8-ac2d-28c60970daaf)]
|
||||
[uuid( 2ac111f2-e492-488e-85df-353c453e98f3)]
|
||||
interface nsIJSRuntimeService : nsISupports
|
||||
{
|
||||
readonly attribute JSRuntime runtime;
|
||||
@ -29,4 +34,11 @@ interface nsIJSRuntimeService : nsISupports
|
||||
*/
|
||||
[noscript, notxpcom] void registerGCCallback(in xpcGCCallback func);
|
||||
[noscript, notxpcom] void unregisterGCCallback(in xpcGCCallback func);
|
||||
|
||||
/**
|
||||
* Register additional context callback which will run after the
|
||||
* standard XPConnect callback.
|
||||
*/
|
||||
[noscript, notxpcom] void registerContextCallback(in xpcContextCallback func);
|
||||
[noscript, notxpcom] void unregisterContextCallback(in xpcContextCallback func);
|
||||
};
|
||||
|
@ -1450,9 +1450,6 @@ nsXPCFunctionThisTranslator::TranslateThis(nsISupports *aInitialThis,
|
||||
|
||||
#endif
|
||||
|
||||
// ContextCallback calls are chained
|
||||
static JSContextCallback gOldJSContextCallback;
|
||||
|
||||
void
|
||||
XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
|
||||
{
|
||||
@ -1466,12 +1463,9 @@ XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
|
||||
xpc::SystemErrorReporterExternal(cx, message, rep);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
static bool
|
||||
ContextCallback(JSContext *cx, unsigned contextOp)
|
||||
{
|
||||
if (gOldJSContextCallback && !gOldJSContextCallback(cx, contextOp))
|
||||
return false;
|
||||
|
||||
if (contextOp == JSCONTEXT_NEW) {
|
||||
JS_SetErrorReporter(cx, XPCShellErrorReporter);
|
||||
JS_SetOperationCallback(cx, XPCShellOperationCallback);
|
||||
@ -1646,7 +1640,7 @@ main(int argc, char **argv, char **envp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
gOldJSContextCallback = JS_SetContextCallback(rt, ContextCallback);
|
||||
rtsvc->RegisterContextCallback(ContextCallback);
|
||||
|
||||
cx = JS_NewContext(rt, 8192);
|
||||
if (!cx) {
|
||||
|
@ -201,19 +201,24 @@ DetachedWrappedNativeProtoMarker(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// GCCallback calls are chained
|
||||
static JSBool
|
||||
ContextCallback(JSContext *cx, unsigned operation)
|
||||
bool
|
||||
XPCJSRuntime::CustomContextCallback(JSContext *cx, unsigned operation)
|
||||
{
|
||||
XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
|
||||
if (self) {
|
||||
if (operation == JSCONTEXT_NEW) {
|
||||
if (!self->OnJSContextNew(cx))
|
||||
return false;
|
||||
} else if (operation == JSCONTEXT_DESTROY) {
|
||||
delete XPCContext::GetXPCContext(cx);
|
||||
if (operation == JSCONTEXT_NEW) {
|
||||
if (!OnJSContextNew(cx)) {
|
||||
return false;
|
||||
}
|
||||
} else if (operation == JSCONTEXT_DESTROY) {
|
||||
delete XPCContext::GetXPCContext(cx);
|
||||
}
|
||||
|
||||
nsTArray<xpcContextCallback> callbacks(extraContextCallbacks);
|
||||
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
|
||||
if (!callbacks[i](cx, operation)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -605,24 +610,6 @@ XPCJSRuntime::GCSliceCallback(JSRuntime *rt,
|
||||
void
|
||||
XPCJSRuntime::CustomGCCallback(JSGCStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case JSGC_BEGIN:
|
||||
{
|
||||
// We seem to sometime lose the unrooted global flag. Restore it
|
||||
// here. FIXME: bug 584495.
|
||||
JSContext *iter = nullptr;
|
||||
while (JSContext *acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
if (!js::HasUnrootedGlobal(acx))
|
||||
JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSGC_END:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<xpcGCCallback> callbacks(extraGCCallbacks);
|
||||
for (uint32_t i = 0; i < callbacks.Length(); ++i)
|
||||
callbacks[i](status);
|
||||
@ -2748,7 +2735,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
#else
|
||||
JS_SetNativeStackQuota(runtime, 128 * sizeof(size_t) * 1024);
|
||||
#endif
|
||||
JS_SetContextCallback(runtime, ContextCallback);
|
||||
JS_SetDestroyCompartmentCallback(runtime, CompartmentDestroyedCallback);
|
||||
JS_SetCompartmentNameCallback(runtime, CompartmentNameCallback);
|
||||
mPrevGCSliceCallback = JS::SetGCSliceCallback(runtime, GCSliceCallback);
|
||||
@ -2869,9 +2855,6 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
|
||||
if (!xpc)
|
||||
return false;
|
||||
|
||||
// we want to mark the global object ourselves since we use a different color
|
||||
JS_ToggleOptions(cx, JSOPTION_UNROOTED_GLOBAL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3064,6 +3047,23 @@ XPCJSRuntime::RemoveGCCallback(xpcGCCallback cb)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XPCJSRuntime::AddContextCallback(xpcContextCallback cb)
|
||||
{
|
||||
NS_ASSERTION(cb, "null callback");
|
||||
extraContextCallbacks.AppendElement(cb);
|
||||
}
|
||||
|
||||
void
|
||||
XPCJSRuntime::RemoveContextCallback(xpcContextCallback cb)
|
||||
{
|
||||
NS_ASSERTION(cb, "null callback");
|
||||
bool found = extraContextCallbacks.RemoveElement(cb);
|
||||
if (!found) {
|
||||
NS_ERROR("Removing a callback which was never added.");
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *
|
||||
XPCJSRuntime::GetJunkScope()
|
||||
{
|
||||
|
@ -1242,6 +1242,20 @@ nsXPConnect::UnregisterGCCallback(xpcGCCallback func)
|
||||
mRuntime->RemoveGCCallback(func);
|
||||
}
|
||||
|
||||
/* [noscript, notxpcom] void registerContextCallback(in xpcContextCallback func); */
|
||||
NS_IMETHODIMP_(void)
|
||||
nsXPConnect::RegisterContextCallback(xpcContextCallback func)
|
||||
{
|
||||
mRuntime->AddContextCallback(func);
|
||||
}
|
||||
|
||||
/* [noscript, notxpcom] void unregisterContextCallback(in xpcContextCallback func); */
|
||||
NS_IMETHODIMP_(void)
|
||||
nsXPConnect::UnregisterContextCallback(xpcContextCallback func)
|
||||
{
|
||||
mRuntime->RemoveContextCallback(func);
|
||||
}
|
||||
|
||||
#ifdef MOZ_JSDEBUGGER
|
||||
void
|
||||
nsXPConnect::CheckForDebugMode(JSRuntime *rt)
|
||||
|
@ -731,6 +731,7 @@ public:
|
||||
void PrepareForCollection() MOZ_OVERRIDE;
|
||||
|
||||
void CustomGCCallback(JSGCStatus status) MOZ_OVERRIDE;
|
||||
bool CustomContextCallback(JSContext *cx, unsigned operation) MOZ_OVERRIDE;
|
||||
static void GCSliceCallback(JSRuntime *rt,
|
||||
JS::GCProgress progress,
|
||||
const JS::GCDescription &desc);
|
||||
@ -817,6 +818,8 @@ public:
|
||||
|
||||
void AddGCCallback(xpcGCCallback cb);
|
||||
void RemoveGCCallback(xpcGCCallback cb);
|
||||
void AddContextCallback(xpcContextCallback cb);
|
||||
void RemoveContextCallback(xpcContextCallback cb);
|
||||
|
||||
static void ActivityCallback(void *arg, JSBool active);
|
||||
static void CTypesActivityCallback(JSContext *cx,
|
||||
@ -864,6 +867,7 @@ private:
|
||||
XPCRootSetElem *mWrappedJSRoots;
|
||||
XPCRootSetElem *mObjectHolderRoots;
|
||||
nsTArray<xpcGCCallback> extraGCCallbacks;
|
||||
nsTArray<xpcContextCallback> extraContextCallbacks;
|
||||
nsRefPtr<WatchdogManager> mWatchdogManager;
|
||||
JS::GCSliceCallback mPrevGCSliceCallback;
|
||||
JSObject* mJunkScope;
|
||||
|
@ -478,10 +478,10 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
bool aExpectUnrootedGlobals)
|
||||
: mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal),
|
||||
mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal),
|
||||
mJSRuntime(nullptr)
|
||||
mJSRuntime(nullptr),
|
||||
mExpectUnrootedGlobals(aExpectUnrootedGlobals)
|
||||
#ifdef DEBUG
|
||||
, mObjectToUnlink(nullptr)
|
||||
, mExpectUnrootedGlobals(aExpectUnrootedGlobals)
|
||||
#endif
|
||||
{
|
||||
mJSRuntime = JS_NewRuntime(aMaxbytes, aUseHelperThreads);
|
||||
@ -494,6 +494,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
}
|
||||
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
|
||||
JS_SetGCCallback(mJSRuntime, GCCallback, this);
|
||||
JS_SetContextCallback(mJSRuntime, ContextCallback, this);
|
||||
|
||||
mJSHolders.Init(512);
|
||||
|
||||
@ -795,6 +796,18 @@ CycleCollectedJSRuntime::GCCallback(JSRuntime* aRuntime,
|
||||
self->OnGC(aStatus);
|
||||
}
|
||||
|
||||
/* static */ JSBool
|
||||
CycleCollectedJSRuntime::ContextCallback(JSContext* aContext,
|
||||
unsigned aOperation,
|
||||
void* aData)
|
||||
{
|
||||
CycleCollectedJSRuntime* self = static_cast<CycleCollectedJSRuntime*>(aData);
|
||||
|
||||
MOZ_ASSERT(JS_GetRuntime(aContext) == self->Runtime());
|
||||
|
||||
return self->OnContext(aContext, aOperation);
|
||||
}
|
||||
|
||||
struct JsGcTracer : public TraceCallbacks
|
||||
{
|
||||
virtual void Trace(JS::Heap<JS::Value> *p, const char *name, void *closure) const MOZ_OVERRIDE {
|
||||
@ -1186,6 +1199,18 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
||||
switch (aStatus) {
|
||||
case JSGC_BEGIN:
|
||||
{
|
||||
// XXXkhuey do we still need this?
|
||||
// We seem to sometime lose the unrooted global flag. Restore it
|
||||
// here. FIXME: bug 584495.
|
||||
if (mExpectUnrootedGlobals){
|
||||
JSContext* iter = nullptr;
|
||||
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
if (!js::HasUnrootedGlobal(acx)) {
|
||||
JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case JSGC_END:
|
||||
@ -1212,3 +1237,15 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
||||
|
||||
CustomGCCallback(aStatus);
|
||||
}
|
||||
|
||||
bool
|
||||
CycleCollectedJSRuntime::OnContext(JSContext* aCx, unsigned aOperation)
|
||||
{
|
||||
if (mExpectUnrootedGlobals && aOperation == JSCONTEXT_NEW) {
|
||||
// XXXkhuey bholley is going to make this go away, but for now XPConnect
|
||||
// needs it.
|
||||
JS_ToggleOptions(aCx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
|
||||
return CustomContextCallback(aCx, aOperation);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class CycleCollectedJSRuntime
|
||||
protected:
|
||||
CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
JSUseHelperThreads aUseHelperThreads,
|
||||
bool aExpectRootedGlobals);
|
||||
bool aExpectUnrootedGlobals);
|
||||
virtual ~CycleCollectedJSRuntime();
|
||||
|
||||
JSRuntime* Runtime() const
|
||||
@ -100,6 +100,10 @@ protected:
|
||||
virtual void TraceAdditionalNativeGrayRoots(JSTracer* aTracer) = 0;
|
||||
|
||||
virtual void CustomGCCallback(JSGCStatus aStatus) {}
|
||||
virtual bool CustomContextCallback(JSContext* aCx, unsigned aOperation)
|
||||
{
|
||||
return true; // Don't block context creation.
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -150,6 +154,8 @@ private:
|
||||
static void TraceBlackJS(JSTracer* aTracer, void* aData);
|
||||
static void TraceGrayJS(JSTracer* aTracer, void* aData);
|
||||
static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);
|
||||
static JSBool ContextCallback(JSContext* aCx, unsigned aOperation,
|
||||
void* aData);
|
||||
|
||||
virtual void TraceNativeBlackRoots(JSTracer* aTracer) { };
|
||||
void TraceNativeGrayRoots(JSTracer* aTracer);
|
||||
@ -162,6 +168,7 @@ private:
|
||||
void FinalizeDeferredThings(DeferredFinalizeType aType);
|
||||
|
||||
void OnGC(JSGCStatus aStatus);
|
||||
bool OnContext(JSContext* aCx, unsigned aOperation);
|
||||
|
||||
public:
|
||||
void AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer);
|
||||
@ -214,9 +221,10 @@ private:
|
||||
|
||||
nsRefPtr<IncrementalFinalizeRunnable> mFinalizeRunnable;
|
||||
|
||||
bool mExpectUnrootedGlobals;
|
||||
|
||||
#ifdef DEBUG
|
||||
void* mObjectToUnlink;
|
||||
bool mExpectUnrootedGlobals;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user