Bug 706885 - Rework Rooting APIs to preserve all available type information; r=billm

This commit is contained in:
Terrence Cole 2013-01-28 18:25:23 -08:00
Родитель 2ba5b077c3
Коммит 35c9f7670d
12 изменённых файлов: 145 добавлений и 158 удалений

Просмотреть файл

@ -79,7 +79,7 @@ struct ListenerData : PRCList
Remove(JSContext* aCx, ListenerData* aListenerData)
{
if (JS::IsIncrementalBarrierNeeded(aCx)) {
JS:: IncrementalReferenceBarrier(aListenerData->mListener);
JS:: IncrementalObjectBarrier(aListenerData->mListener);
}
PR_REMOVE_LINK(aListenerData);

Просмотреть файл

@ -159,11 +159,14 @@ extern JS_FRIEND_API(bool)
IsIncrementalBarrierNeeded(JSContext *cx);
extern JS_FRIEND_API(void)
IncrementalReferenceBarrier(void *ptr);
IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind);
extern JS_FRIEND_API(void)
IncrementalValueBarrier(const Value &v);
extern JS_FRIEND_API(void)
IncrementalObjectBarrier(JSObject *obj);
extern JS_FRIEND_API(void)
PokeGC(JSRuntime *rt);
@ -185,7 +188,7 @@ class ObjectPtr
void finalize(JSRuntime *rt) {
if (IsIncrementalBarrierNeeded(rt))
IncrementalReferenceBarrier(value);
IncrementalObjectBarrier(value);
value = NULL;
}
@ -194,11 +197,11 @@ class ObjectPtr
JSObject *get() const { return value; }
void writeBarrierPre(JSRuntime *rt) {
IncrementalReferenceBarrier(value);
IncrementalObjectBarrier(value);
}
ObjectPtr &operator=(JSObject *obj) {
IncrementalReferenceBarrier(value);
IncrementalObjectBarrier(value);
value = obj;
return *this;
}
@ -229,7 +232,7 @@ ExposeGCThingToActiveJS(void *thing, JSGCTraceKind kind)
if (GCThingIsMarkedGray(thing))
UnmarkGrayGCThingRecursively(thing, kind);
else if (IsIncrementalBarrierNeededOnGCThing(thing, kind))
IncrementalReferenceBarrier(thing);
IncrementalReferenceBarrier(thing, kind);
}
static JS_ALWAYS_INLINE void

Просмотреть файл

@ -689,8 +689,12 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
for (RootRange r = rt->gcRootsHash.all(); !r.empty(); r.popFront()) {
const RootEntry &entry = r.front();
const char *name = entry.value.name ? entry.value.name : "root";
if (entry.value.type == JS_GC_ROOT_GCTHING_PTR)
MarkGCThingRoot(trc, reinterpret_cast<void **>(entry.key), name);
if (entry.value.type == JS_GC_ROOT_STRING_PTR)
MarkStringRoot(trc, reinterpret_cast<JSString **>(entry.key), name);
else if (entry.value.type == JS_GC_ROOT_OBJECT_PTR)
MarkObjectRoot(trc, reinterpret_cast<JSObject **>(entry.key), name);
else if (entry.value.type == JS_GC_ROOT_SCRIPT_PTR)
MarkScriptRoot(trc, reinterpret_cast<JSScript **>(entry.key), name);
else
MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
}

Просмотреть файл

@ -2322,7 +2322,7 @@ JS_AddValueRoot(JSContext *cx, jsval *vp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddRoot(cx, vp, NULL);
return AddValueRoot(cx, vp, NULL);
}
JS_PUBLIC_API(JSBool)
@ -2330,7 +2330,7 @@ JS_AddStringRoot(JSContext *cx, JSString **rp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, NULL);
return AddStringRoot(cx, rp, NULL);
}
JS_PUBLIC_API(JSBool)
@ -2338,15 +2338,7 @@ JS_AddObjectRoot(JSContext *cx, JSObject **rp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, NULL);
}
JS_PUBLIC_API(JSBool)
JS_AddGCThingRoot(JSContext *cx, void **rp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, NULL);
return AddObjectRoot(cx, rp, NULL);
}
JS_PUBLIC_API(JSBool)
@ -2354,7 +2346,13 @@ JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddRoot(cx, vp, name);
return AddValueRoot(cx, vp, name);
}
JS_PUBLIC_API(JSBool)
JS_AddNamedValueRootRT(JSRuntime *rt, jsval *vp, const char *name)
{
return AddValueRootRT(rt, vp, name);
}
JS_PUBLIC_API(JSBool)
@ -2362,7 +2360,7 @@ JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, name);
return AddStringRoot(cx, rp, name);
}
JS_PUBLIC_API(JSBool)
@ -2370,7 +2368,7 @@ JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, name);
return AddObjectRoot(cx, rp, name);
}
JS_PUBLIC_API(JSBool)
@ -2378,15 +2376,7 @@ JS_AddNamedScriptRoot(JSContext *cx, JSScript **rp, const char *name)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, name);
}
JS_PUBLIC_API(JSBool)
JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return js_AddGCThingRoot(cx, (void **)rp, name);
return AddScriptRoot(cx, rp, name);
}
/* We allow unrooting from finalizers within the GC */
@ -2419,13 +2409,6 @@ JS_RemoveScriptRoot(JSContext *cx, JSScript **rp)
js_RemoveRoot(cx->runtime, (void *)rp);
}
JS_PUBLIC_API(void)
JS_RemoveGCThingRoot(JSContext *cx, void **rp)
{
CHECK_REQUEST(cx);
js_RemoveRoot(cx->runtime, (void *)rp);
}
JS_PUBLIC_API(void)
JS_RemoveValueRootRT(JSRuntime *rt, jsval *vp)
{
@ -2456,37 +2439,15 @@ JS_AnchorPtr(void *p)
}
JS_PUBLIC_API(JSBool)
JS_LockGCThing(JSContext *cx, void *thing)
JS_LockGCThingRT(JSRuntime *rt, void *gcthing)
{
JSBool ok;
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
ok = js_LockGCThingRT(cx->runtime, thing);
if (!ok)
JS_ReportOutOfMemory(cx);
return ok;
return js_LockThing(rt, gcthing);
}
JS_PUBLIC_API(JSBool)
JS_LockGCThingRT(JSRuntime *rt, void *thing)
JS_UnlockGCThingRT(JSRuntime *rt, void *gcthing)
{
return js_LockGCThingRT(rt, thing);
}
JS_PUBLIC_API(JSBool)
JS_UnlockGCThing(JSContext *cx, void *thing)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
js_UnlockGCThingRT(cx->runtime, thing);
return true;
}
JS_PUBLIC_API(JSBool)
JS_UnlockGCThingRT(JSRuntime *rt, void *thing)
{
js_UnlockGCThingRT(rt, thing);
js_UnlockThing(rt, gcthing);
return true;
}
@ -6922,7 +6883,7 @@ JS_SaveExceptionState(JSContext *cx)
if (state) {
state->throwing = JS_GetPendingException(cx, &state->exception);
if (state->throwing && JSVAL_IS_GCTHING(state->exception))
js_AddRoot(cx, &state->exception, "JSExceptionState.exception");
AddValueRoot(cx, &state->exception, "JSExceptionState.exception");
}
return state;
}

Просмотреть файл

@ -3604,21 +3604,20 @@ JS_AddStringRoot(JSContext *cx, JSString **rp);
extern JS_PUBLIC_API(JSBool)
JS_AddObjectRoot(JSContext *cx, JSObject **rp);
extern JS_PUBLIC_API(JSBool)
JS_AddGCThingRoot(JSContext *cx, void **rp);
#ifdef NAME_ALL_GC_ROOTS
#define JS_DEFINE_TO_TOKEN(def) #def
#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def)
#define JS_AddValueRoot(cx,vp) JS_AddNamedValueRoot((cx), (vp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddStringRoot(cx,rp) JS_AddNamedStringRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddObjectRoot(cx,rp) JS_AddNamedObjectRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddGCThingRoot(cx,rp) JS_AddNamedGCThingRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#endif
extern JS_PUBLIC_API(JSBool)
JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name);
extern JS_PUBLIC_API(JSBool)
JS_AddNamedValueRootRT(JSRuntime *rt, jsval *vp, const char *name);
extern JS_PUBLIC_API(JSBool)
JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name);
@ -3628,9 +3627,6 @@ JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name);
extern JS_PUBLIC_API(JSBool)
JS_AddNamedScriptRoot(JSContext *cx, JSScript **rp, const char *name);
extern JS_PUBLIC_API(JSBool)
JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name);
extern JS_PUBLIC_API(void)
JS_RemoveValueRoot(JSContext *cx, jsval *vp);
@ -3643,9 +3639,6 @@ JS_RemoveObjectRoot(JSContext *cx, JSObject **rp);
extern JS_PUBLIC_API(void)
JS_RemoveScriptRoot(JSContext *cx, JSScript **rp);
extern JS_PUBLIC_API(void)
JS_RemoveGCThingRoot(JSContext *cx, void **rp);
extern JS_PUBLIC_API(void)
JS_RemoveValueRootRT(JSRuntime *rt, jsval *vp);
@ -3660,12 +3653,6 @@ JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp);
/* TODO: remove these APIs */
extern JS_FRIEND_API(JSBool)
js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name);
extern JS_FRIEND_API(JSBool)
js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name);
extern JS_FRIEND_API(void)
js_RemoveRoot(JSRuntime *rt, void *rp);
@ -3676,22 +3663,11 @@ js_RemoveRoot(JSRuntime *rt, void *rp);
extern JS_NEVER_INLINE JS_PUBLIC_API(void)
JS_AnchorPtr(void *p);
typedef enum JSGCRootType {
JS_GC_ROOT_VALUE_PTR,
JS_GC_ROOT_GCTHING_PTR
} JSGCRootType;
extern JS_PUBLIC_API(JSBool)
JS_LockGCThingRT(JSRuntime *rt, void *gcthing);
extern JS_PUBLIC_API(JSBool)
JS_LockGCThing(JSContext *cx, void *thing);
extern JS_PUBLIC_API(JSBool)
JS_LockGCThingRT(JSRuntime *rt, void *thing);
extern JS_PUBLIC_API(JSBool)
JS_UnlockGCThing(JSContext *cx, void *thing);
extern JS_PUBLIC_API(JSBool)
JS_UnlockGCThingRT(JSRuntime *rt, void *thing);
JS_UnlockGCThingRT(JSRuntime *rt, void *gcthing);
/*
* Register externally maintained GC roots.

Просмотреть файл

@ -694,10 +694,10 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj_, JSPropertyDescArray *pda)
for (i = 0; i < props.length(); ++i) {
pd[i].id = JSVAL_NULL;
pd[i].value = JSVAL_NULL;
if (!js_AddRoot(cx, &pd[i].id, NULL))
if (!AddValueRoot(cx, &pd[i].id, NULL))
goto bad;
pd[i].id = IdToValue(props[i]);
if (!js_AddRoot(cx, &pd[i].value, NULL))
if (!AddValueRoot(cx, &pd[i].value, NULL))
goto bad;
if (!Proxy::get(cx, obj, obj, props.handleAt(i), MutableHandleValue::fromMarkedLocation(&pd[i].value)))
goto bad;
@ -737,14 +737,14 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj_, JSPropertyDescArray *pda)
pd[i].id = JSVAL_NULL;
pd[i].value = JSVAL_NULL;
pd[i].alias = JSVAL_NULL;
if (!js_AddRoot(cx, &pd[i].id, NULL))
if (!AddValueRoot(cx, &pd[i].id, NULL))
goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL))
if (!AddValueRoot(cx, &pd[i].value, NULL))
goto bad;
shape = const_cast<Shape *>(&r.front());
if (!GetPropertyDesc(cx, obj, shape, &pd[i]))
goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
if ((pd[i].flags & JSPD_ALIAS) && !AddValueRoot(cx, &pd[i].alias, NULL))
goto bad;
if (++i == obj->propertyCount())
break;

Просмотреть файл

@ -11,6 +11,7 @@
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsfriendapi.h"
#include "jsgc.h"
#include "jswrapper.h"
#include "jsweakmap.h"
#include "jswatchpoint.h"
@ -871,27 +872,41 @@ JS::IsIncrementalBarrierNeeded(JSContext *cx)
}
JS_FRIEND_API(void)
JS::IncrementalReferenceBarrier(void *ptr)
JS::IncrementalObjectBarrier(JSObject *obj)
{
if (!obj)
return;
JS_ASSERT(!obj->compartment()->rt->isHeapBusy());
AutoMarkInDeadCompartment amn(obj->compartment());
JSObject::writeBarrierPre(obj);
}
JS_FRIEND_API(void)
JS::IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind)
{
if (!ptr)
return;
gc::Cell *cell = static_cast<gc::Cell *>(ptr);
JS_ASSERT(!cell->compartment()->rt->isHeapBusy());
JSCompartment *comp = cell->compartment();
AutoMarkInDeadCompartment amn(cell->compartment());
JS_ASSERT(!comp->rt->isHeapBusy());
AutoMarkInDeadCompartment amn(comp);
uint32_t kind = gc::GetGCThingTraceKind(ptr);
if (kind == JSTRACE_OBJECT)
JSObject::writeBarrierPre(reinterpret_cast<RawObject>(ptr));
JSObject::writeBarrierPre(static_cast<JSObject*>(cell));
else if (kind == JSTRACE_STRING)
JSString::writeBarrierPre(reinterpret_cast<RawString>(ptr));
JSString::writeBarrierPre(static_cast<JSString*>(cell));
else if (kind == JSTRACE_SCRIPT)
JSScript::writeBarrierPre(reinterpret_cast<RawScript>(ptr));
JSScript::writeBarrierPre(static_cast<JSScript*>(cell));
else if (kind == JSTRACE_SHAPE)
Shape::writeBarrierPre(reinterpret_cast<RawShape>(ptr));
Shape::writeBarrierPre(static_cast<Shape*>(cell));
else if (kind == JSTRACE_BASE_SHAPE)
BaseShape::writeBarrierPre(reinterpret_cast<RawBaseShape>(ptr));
BaseShape::writeBarrierPre(static_cast<BaseShape*>(cell));
else if (kind == JSTRACE_TYPE_OBJECT)
types::TypeObject::writeBarrierPre((types::TypeObject *) ptr);
else

Просмотреть файл

@ -1030,26 +1030,13 @@ js_FinishGC(JSRuntime *rt)
rt->gcLocksHash.clear();
}
JSBool
js_AddRoot(JSContext *cx, Value *vp, const char *name)
{
JSBool ok = js_AddRootRT(cx->runtime, vp, name);
if (!ok)
JS_ReportOutOfMemory(cx);
return ok;
}
template <typename T> struct BarrierOwner {};
template <typename T> struct BarrierOwner<T *> { typedef T result; };
template <> struct BarrierOwner<Value> { typedef HeapValue result; };
JSBool
js_AddGCThingRoot(JSContext *cx, void **rp, const char *name)
{
JSBool ok = js_AddGCThingRootRT(cx->runtime, rp, name);
if (!ok)
JS_ReportOutOfMemory(cx);
return ok;
}
JS_FRIEND_API(JSBool)
js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name)
template <typename T>
static bool
AddRoot(JSRuntime *rt, T *rp, const char *name, JSGCRootType rootType)
{
/*
* Sometimes Firefox will hold weak references to objects and then convert
@ -1058,26 +1045,49 @@ js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name)
* cases.
*/
if (rt->gcIncrementalState != NO_INCREMENTAL)
IncrementalValueBarrier(*vp);
BarrierOwner<T>::result::writeBarrierPre(*rp);
return !!rt->gcRootsHash.put((void *)vp,
RootInfo(name, JS_GC_ROOT_VALUE_PTR));
return rt->gcRootsHash.put((void *)rp, RootInfo(name, rootType));
}
JS_FRIEND_API(JSBool)
js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name)
template <typename T>
static bool
AddRoot(JSContext *cx, T *rp, const char *name, JSGCRootType rootType)
{
/*
* Sometimes Firefox will hold weak references to objects and then convert
* them to strong references by calling AddRoot (e.g., via PreserveWrapper,
* or ModifyBusyCount in workers). We need a read barrier to cover these
* cases.
*/
if (rt->gcIncrementalState != NO_INCREMENTAL)
IncrementalReferenceBarrier(*rp);
bool ok = AddRoot(cx->runtime, rp, name, rootType);
if (!ok)
JS_ReportOutOfMemory(cx);
return ok;
}
return !!rt->gcRootsHash.put((void *)rp,
RootInfo(name, JS_GC_ROOT_GCTHING_PTR));
JSBool
js::AddValueRoot(JSContext *cx, Value *vp, const char *name)
{
return AddRoot(cx, vp, name, JS_GC_ROOT_VALUE_PTR);
}
extern JSBool
js::AddValueRootRT(JSRuntime *rt, js::Value *vp, const char *name)
{
return AddRoot(rt, vp, name, JS_GC_ROOT_VALUE_PTR);
}
extern JSBool
js::AddStringRoot(JSContext *cx, JSString **rp, const char *name)
{
return AddRoot(cx, rp, name, JS_GC_ROOT_STRING_PTR);
}
extern JSBool
js::AddObjectRoot(JSContext *cx, JSObject **rp, const char *name)
{
return AddRoot(cx, rp, name, JS_GC_ROOT_OBJECT_PTR);
}
extern JSBool
js::AddScriptRoot(JSContext *cx, JSScript **rp, const char *name)
{
return AddRoot(cx, rp, name, JS_GC_ROOT_SCRIPT_PTR);
}
JS_FRIEND_API(void)
@ -1566,7 +1576,7 @@ js_GetGCThingTraceKind(void *thing)
}
JSBool
js_LockGCThingRT(JSRuntime *rt, void *thing)
js_LockThing(JSRuntime *rt, void *thing)
{
if (!thing)
return true;
@ -1578,7 +1588,7 @@ js_LockGCThingRT(JSRuntime *rt, void *thing)
* cases.
*/
if (rt->gcIncrementalState != NO_INCREMENTAL)
IncrementalReferenceBarrier(thing);
IncrementalReferenceBarrier(thing, GetGCThingTraceKind(thing));
if (GCLocks::Ptr p = rt->gcLocksHash.lookupWithDefault(thing, 0)) {
p->value++;
@ -1589,7 +1599,7 @@ js_LockGCThingRT(JSRuntime *rt, void *thing)
}
void
js_UnlockGCThingRT(JSRuntime *rt, void *thing)
js_UnlockThing(JSRuntime *rt, void *thing)
{
if (!thing)
return;

Просмотреть файл

@ -120,6 +120,7 @@ MapAllocToTraceKind(AllocKind kind)
return map[kind];
}
#ifdef JSGC_GENERATIONAL
static inline bool
IsNurseryAllocable(AllocKind kind)
{
@ -152,6 +153,7 @@ IsNurseryAllocable(AllocKind kind)
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(map) == FINALIZE_LIMIT);
return map[kind];
}
#endif
static inline bool
IsBackgroundFinalized(AllocKind kind)
@ -487,6 +489,13 @@ struct GCPtrHasher
typedef HashMap<void *, uint32_t, GCPtrHasher, SystemAllocPolicy> GCLocks;
typedef enum JSGCRootType {
JS_GC_ROOT_VALUE_PTR,
JS_GC_ROOT_STRING_PTR,
JS_GC_ROOT_OBJECT_PTR,
JS_GC_ROOT_SCRIPT_PTR
} JSGCRootType;
struct RootInfo {
RootInfo() {}
RootInfo(const char *name, JSGCRootType type) : name(name), type(type) {}
@ -499,6 +508,21 @@ typedef js::HashMap<void *,
js::DefaultHasher<void *>,
js::SystemAllocPolicy> RootedValueMap;
extern JSBool
AddValueRoot(JSContext *cx, js::Value *vp, const char *name);
extern JSBool
AddValueRootRT(JSRuntime *rt, js::Value *vp, const char *name);
extern JSBool
AddStringRoot(JSContext *cx, JSString **rp, const char *name);
extern JSBool
AddObjectRoot(JSContext *cx, JSObject **rp, const char *name);
extern JSBool
AddScriptRoot(JSContext *cx, JSScript **rp, const char *name);
} /* namespace js */
extern JSBool
@ -507,12 +531,6 @@ js_InitGC(JSRuntime *rt, uint32_t maxbytes);
extern void
js_FinishGC(JSRuntime *rt);
extern JSBool
js_AddRoot(JSContext *cx, js::Value *vp, const char *name);
extern JSBool
js_AddGCThingRoot(JSContext *cx, void **rp, const char *name);
/* Table of pointers with count valid members. */
typedef struct JSPtrTable {
size_t count;
@ -520,10 +538,10 @@ typedef struct JSPtrTable {
} JSPtrTable;
extern JSBool
js_LockGCThingRT(JSRuntime *rt, void *thing);
js_LockThing(JSRuntime *rt, void *thing);
extern void
js_UnlockGCThingRT(JSRuntime *rt, void *thing);
js_UnlockThing(JSRuntime *rt, void *thing);
namespace js {

Просмотреть файл

@ -69,7 +69,7 @@ public:
mRt = nullptr;
}
if (!mRt && js_AddRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
if (!mRt && JS_AddNamedValueRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
mRt = aRt;
}
@ -84,7 +84,7 @@ public:
jsval oldval = mVal;
if (mRt) {
js_RemoveRoot(mRt, &mVal); // infallible
JS_RemoveValueRootRT(mRt, &mVal); // infallible
mRt = nullptr;
}

Просмотреть файл

@ -944,7 +944,7 @@ XPCWrappedNative::Destroy()
*/
if (XPCJSRuntime *rt = GetRuntime()) {
if (js::IsIncrementalBarrierNeeded(rt->GetJSRuntime()))
js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
js::IncrementalObjectBarrier(GetWrapperPreserveColor());
mWrapperWord = WRAPPER_WORD_POISON;
} else {
MOZ_ASSERT(mWrapperWord == WRAPPER_WORD_POISON);

Просмотреть файл

@ -2910,7 +2910,7 @@ public:
}
void SetWrapper(JSObject *obj)
{
js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
js::IncrementalObjectBarrier(GetWrapperPreserveColor());
intptr_t newval = intptr_t(obj) | (mWrapperWord & FLAG_MASK);
mWrapperWord = newval;
}