зеркало из https://github.com/mozilla/gecko-dev.git
Bug 706885 - Rework Rooting APIs to preserve all available type information; r=billm
This commit is contained in:
Родитель
2ba5b077c3
Коммит
35c9f7670d
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче