mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 716033 - Move write barriers from jsapi.h to jsfriendapi.h (r=luke,bholley)
This commit is contained in:
parent
6924b97c89
commit
37bab689c0
@ -6714,79 +6714,6 @@ js_GetCompartmentPrivate(JSCompartment *compartment)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_RegisterReference(void **ref)
|
||||
{
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ModifyReference(void **ref, void *newval)
|
||||
{
|
||||
// XPConnect uses the lower bits of its JSObject refs for evil purposes,
|
||||
// so we need to fix this.
|
||||
void *thing = *ref;
|
||||
*ref = newval;
|
||||
thing = (void *)((uintptr_t)thing & ~7);
|
||||
if (!thing)
|
||||
return;
|
||||
JS_ASSERT(!static_cast<gc::Cell *>(thing)->compartment()->rt->gcRunning);
|
||||
uint32_t kind = GetGCThingTraceKind(thing);
|
||||
if (kind == JSTRACE_OBJECT)
|
||||
JSObject::writeBarrierPre((JSObject *) thing);
|
||||
else if (kind == JSTRACE_STRING)
|
||||
JSString::writeBarrierPre((JSString *) thing);
|
||||
else
|
||||
JS_NOT_REACHED("invalid trace kind");
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_UnregisterReference(void **ref)
|
||||
{
|
||||
// For now we just want to trigger a write barrier.
|
||||
JS_ModifyReference(ref, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_UnregisterReferenceRT(JSRuntime *rt, void **ref)
|
||||
{
|
||||
// For now we just want to trigger a write barrier.
|
||||
if (!rt->gcRunning)
|
||||
JS_ModifyReference(ref, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_RegisterValue(jsval *val)
|
||||
{
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ModifyValue(jsval *val, jsval newval)
|
||||
{
|
||||
HeapValue::writeBarrierPre(*val);
|
||||
*val = newval;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_UnregisterValue(jsval *val)
|
||||
{
|
||||
JS_ModifyValue(val, JSVAL_VOID);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_UnregisterValueRT(JSRuntime *rt, jsval *val)
|
||||
{
|
||||
if (!rt->gcRunning)
|
||||
JS_ModifyValue(val, JSVAL_VOID);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSTracer *)
|
||||
JS_GetIncrementalGCTracer(JSRuntime *rt)
|
||||
{
|
||||
return rt->gcIncrementalTracer;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#if !defined(STATIC_EXPORTABLE_JS_API) && !defined(STATIC_JS_API) && defined(XP_WIN)
|
||||
|
||||
#include "jswin.h"
|
||||
|
@ -3227,105 +3227,6 @@ JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, JSGCTraceKind kind,
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write barrier API.
|
||||
*
|
||||
* This API is used to inform SpiderMonkey of pointers to JS GC things in the
|
||||
* malloc heap. There is no need to use this API unless incremental GC is
|
||||
* enabled. When they are, the requirements for using the API are as follows:
|
||||
*
|
||||
* All pointers to JS GC things from the malloc heap must be registered and
|
||||
* unregistered with the API functions below. This is *in addition* to the
|
||||
* normal rooting and tracing that must be done normally--these functions will
|
||||
* not take care of rooting for you.
|
||||
*
|
||||
* Besides registration, the JS_ModifyReference function must be called to
|
||||
* change the value of these references. You should not change them using
|
||||
* assignment.
|
||||
*
|
||||
* Only the RT versions of these functions (which take a JSRuntime argument)
|
||||
* should be called during GC. Without a JSRuntime, it is not possible to know
|
||||
* if the object being barriered has already been finalized.
|
||||
*
|
||||
* To avoid the headache of using these API functions, the JSBarrieredObjectPtr
|
||||
* C++ class is provided--simply replace your JSObject* with a
|
||||
* JSBarrieredObjectPtr. It will take care of calling the registration and
|
||||
* modification APIs.
|
||||
*
|
||||
* For more explanation, see the comment in gc/Barrier.h.
|
||||
*/
|
||||
|
||||
/* These functions are to be used for objects and strings. */
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_RegisterReference(void **ref);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ModifyReference(void **ref, void *newval);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_UnregisterReference(void **ref);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_UnregisterReferenceRT(JSRuntime *rt, void **ref);
|
||||
|
||||
/* These functions are for values. */
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_RegisterValue(jsval *val);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ModifyValue(jsval *val, jsval newval);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_UnregisterValue(jsval *val);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_UnregisterValueRT(JSRuntime *rt, jsval *val);
|
||||
|
||||
extern JS_PUBLIC_API(JSTracer *)
|
||||
JS_GetIncrementalGCTracer(JSRuntime *rt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
namespace JS {
|
||||
|
||||
class HeapPtrObject
|
||||
{
|
||||
JSObject *value;
|
||||
|
||||
public:
|
||||
HeapPtrObject() : value(NULL) { JS_RegisterReference((void **) &value); }
|
||||
|
||||
HeapPtrObject(JSObject *obj) : value(obj) { JS_RegisterReference((void **) &value); }
|
||||
|
||||
/* Always call finalize before the destructor. */
|
||||
~HeapPtrObject() { JS_ASSERT(!value); }
|
||||
|
||||
void finalize(JSRuntime *rt) {
|
||||
JS_UnregisterReferenceRT(rt, (void **) &value);
|
||||
value = NULL;
|
||||
}
|
||||
void finalize(JSContext *cx) { finalize(JS_GetRuntime(cx)); }
|
||||
|
||||
void init(JSObject *obj) { value = obj; }
|
||||
|
||||
JSObject *get() const { return value; }
|
||||
|
||||
HeapPtrObject &operator=(JSObject *obj) {
|
||||
JS_ModifyReference((void **) &value, obj);
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSObject &operator*() const { return *value; }
|
||||
JSObject *operator->() const { return value; }
|
||||
operator JSObject *() const { return value; }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Garbage collector API.
|
||||
*/
|
||||
|
@ -469,6 +469,39 @@ js::DumpHeapComplete(JSContext *cx, FILE *fp)
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt)
|
||||
{
|
||||
return !!rt->gcIncrementalTracer && !rt->gcRunning;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx)
|
||||
{
|
||||
return IsIncrementalBarrierNeeded(cx->runtime);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
JS_ASSERT(!static_cast<gc::Cell *>(ptr)->compartment()->rt->gcRunning);
|
||||
uint32_t kind = gc::GetGCThingTraceKind(ptr);
|
||||
if (kind == JSTRACE_OBJECT)
|
||||
JSObject::writeBarrierPre((JSObject *) ptr);
|
||||
else if (kind == JSTRACE_STRING)
|
||||
JSString::writeBarrierPre((JSString *) ptr);
|
||||
else
|
||||
JS_NOT_REACHED("invalid trace kind");
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalValueBarrier(const Value &v)
|
||||
{
|
||||
HeapValue::writeBarrierPre(v);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
AutoLockGC::LockGC(JSRuntime *rt)
|
||||
{
|
||||
|
@ -565,6 +565,56 @@ GetRuntimeCompartments(JSRuntime *rt);
|
||||
extern JS_FRIEND_API(size_t)
|
||||
SizeOfJSContext();
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalValueBarrier(const Value &v);
|
||||
|
||||
class ObjectPtr
|
||||
{
|
||||
JSObject *value;
|
||||
|
||||
public:
|
||||
ObjectPtr() : value(NULL) {}
|
||||
|
||||
ObjectPtr(JSObject *obj) : value(obj) {}
|
||||
|
||||
/* Always call finalize before the destructor. */
|
||||
~ObjectPtr() { JS_ASSERT(!value); }
|
||||
|
||||
void finalize(JSRuntime *rt) {
|
||||
if (IsIncrementalBarrierNeeded(rt))
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = NULL;
|
||||
}
|
||||
void finalize(JSContext *cx) { finalize(JS_GetRuntime(cx)); }
|
||||
|
||||
void init(JSObject *obj) { value = obj; }
|
||||
|
||||
JSObject *get() const { return value; }
|
||||
|
||||
void writeBarrierPre(JSRuntime *rt) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
}
|
||||
|
||||
ObjectPtr &operator=(JSObject *obj) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = obj;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSObject &operator*() const { return *value; }
|
||||
JSObject *operator->() const { return value; }
|
||||
operator JSObject *() const { return value; }
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
|
@ -826,8 +826,6 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
|
||||
NS_ASSERTION(mSet, "bad ctor param");
|
||||
|
||||
DEBUG_TrackNewWrapper(this);
|
||||
|
||||
JS_RegisterReference((void **) &mWrapperWord);
|
||||
}
|
||||
|
||||
// This ctor is used if this object will NOT have a proto.
|
||||
@ -850,8 +848,6 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
|
||||
NS_ASSERTION(aSet, "bad ctor param");
|
||||
|
||||
DEBUG_TrackNewWrapper(this);
|
||||
|
||||
JS_RegisterReference((void **) &mWrapperWord);
|
||||
}
|
||||
|
||||
XPCWrappedNative::~XPCWrappedNative()
|
||||
@ -909,7 +905,8 @@ XPCWrappedNative::Destroy()
|
||||
* the first time because mWrapperWord isn't used afterwards.
|
||||
*/
|
||||
if (XPCJSRuntime *rt = GetRuntime()) {
|
||||
JS_UnregisterReferenceRT(rt->GetJSRuntime(), (void **) &mWrapperWord);
|
||||
if (js::IsIncrementalBarrierNeeded(rt->GetJSRuntime()))
|
||||
js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
|
||||
mWrapperWord = WRAPPER_WORD_POISON;
|
||||
} else {
|
||||
MOZ_ASSERT(mWrapperWord == WRAPPER_WORD_POISON);
|
||||
@ -925,7 +922,7 @@ XPCWrappedNative::UpdateScriptableInfo(XPCNativeScriptableInfo *si)
|
||||
|
||||
// Write barrier for incremental GC.
|
||||
JSRuntime* rt = GetRuntime()->GetJSRuntime();
|
||||
if (JS_GetIncrementalGCTracer(rt))
|
||||
if (js::IsIncrementalBarrierNeeded(rt))
|
||||
mScriptableInfo->Mark();
|
||||
|
||||
mScriptableInfo = si;
|
||||
@ -936,12 +933,11 @@ XPCWrappedNative::SetProto(XPCWrappedNativeProto* p)
|
||||
{
|
||||
NS_ASSERTION(!IsWrapperExpired(), "bad ptr!");
|
||||
|
||||
MOZ_ASSERT(HasProto());
|
||||
|
||||
// Write barrier for incremental GC.
|
||||
if (HasProto()) {
|
||||
JSRuntime* rt = GetRuntime()->GetJSRuntime();
|
||||
if (JS_GetIncrementalGCTracer(rt))
|
||||
GetProto()->TraceJS(JS_GetIncrementalGCTracer(rt));
|
||||
}
|
||||
JSRuntime* rt = GetRuntime()->GetJSRuntime();
|
||||
GetProto()->WriteBarrierPre(rt);
|
||||
|
||||
mMaybeProto = p;
|
||||
}
|
||||
|
@ -1654,10 +1654,10 @@ private:
|
||||
// default parent for the XPCWrappedNatives that have us as the scope,
|
||||
// unless a PreCreate hook overrides it. Note that this _may_ be null (see
|
||||
// constructor).
|
||||
JS::HeapPtrObject mGlobalJSObject;
|
||||
js::ObjectPtr mGlobalJSObject;
|
||||
|
||||
// Cached value of Object.prototype
|
||||
JS::HeapPtrObject mPrototypeJSObject;
|
||||
js::ObjectPtr mPrototypeJSObject;
|
||||
// Prototype to use for wrappers with no helper.
|
||||
JSObject* mPrototypeNoHelper;
|
||||
|
||||
@ -2306,6 +2306,12 @@ public:
|
||||
mScriptableInfo->Mark();
|
||||
}
|
||||
|
||||
void WriteBarrierPre(JSRuntime* rt)
|
||||
{
|
||||
if (js::IsIncrementalBarrierNeeded(rt) && mJSProtoObject)
|
||||
mJSProtoObject.writeBarrierPre(rt);
|
||||
}
|
||||
|
||||
// NOP. This is just here to make the AutoMarkingPtr code compile.
|
||||
inline void AutoTrace(JSTracer* trc) {}
|
||||
|
||||
@ -2348,7 +2354,7 @@ private:
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope* mScope;
|
||||
JS::HeapPtrObject mJSProtoObject;
|
||||
js::ObjectPtr mJSProtoObject;
|
||||
nsCOMPtr<nsIClassInfo> mClassInfo;
|
||||
PRUint32 mClassInfoFlags;
|
||||
XPCNativeSet* mSet;
|
||||
@ -2737,8 +2743,9 @@ public:
|
||||
}
|
||||
void SetWrapper(JSObject *obj)
|
||||
{
|
||||
js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
|
||||
PRWord newval = PRWord(obj) | (mWrapperWord & FLAG_MASK);
|
||||
JS_ModifyReference((void **)&mWrapperWord, (void *)newval);
|
||||
mWrapperWord = newval;
|
||||
}
|
||||
|
||||
void NoteTearoffs(nsCycleCollectionTraversalCallback& cb);
|
||||
|
Loading…
Reference in New Issue
Block a user