mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 16:46:26 +00:00
Bug 855350 - GC: Add CustomAutoRooter and use it internally r=terrence
This commit is contained in:
parent
c4b1a4ed44
commit
6db07a6d40
@ -530,53 +530,6 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
return;
|
||||
}
|
||||
|
||||
case PROPDESC: {
|
||||
PropDesc::AutoRooter *rooter = static_cast<PropDesc::AutoRooter *>(this);
|
||||
MarkValueRoot(trc, &rooter->pd->pd_, "PropDesc::AutoRooter pd");
|
||||
MarkValueRoot(trc, &rooter->pd->value_, "PropDesc::AutoRooter value");
|
||||
MarkValueRoot(trc, &rooter->pd->get_, "PropDesc::AutoRooter get");
|
||||
MarkValueRoot(trc, &rooter->pd->set_, "PropDesc::AutoRooter set");
|
||||
return;
|
||||
}
|
||||
|
||||
case STACKSHAPE: {
|
||||
StackShape::AutoRooter *rooter = static_cast<StackShape::AutoRooter *>(this);
|
||||
if (rooter->shape->base)
|
||||
MarkBaseShapeRoot(trc, (BaseShape**) &rooter->shape->base, "StackShape::AutoRooter base");
|
||||
MarkIdRoot(trc, (jsid*) &rooter->shape->propid, "StackShape::AutoRooter id");
|
||||
return;
|
||||
}
|
||||
|
||||
case STACKBASESHAPE: {
|
||||
StackBaseShape::AutoRooter *rooter = static_cast<StackBaseShape::AutoRooter *>(this);
|
||||
if (rooter->base->parent)
|
||||
MarkObjectRoot(trc, (JSObject**) &rooter->base->parent, "StackBaseShape::AutoRooter parent");
|
||||
if ((rooter->base->flags & BaseShape::HAS_GETTER_OBJECT) && rooter->base->rawGetter) {
|
||||
MarkObjectRoot(trc, (JSObject**) &rooter->base->rawGetter,
|
||||
"StackBaseShape::AutoRooter getter");
|
||||
}
|
||||
if ((rooter->base->flags & BaseShape::HAS_SETTER_OBJECT) && rooter->base->rawSetter) {
|
||||
MarkObjectRoot(trc, (JSObject**) &rooter->base->rawSetter,
|
||||
"StackBaseShape::AutoRooter setter");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case GETTERSETTER: {
|
||||
AutoRooterGetterSetter::Inner *rooter = static_cast<AutoRooterGetterSetter::Inner *>(this);
|
||||
if ((rooter->attrs & JSPROP_GETTER) && *rooter->pgetter)
|
||||
MarkObjectRoot(trc, (JSObject**) rooter->pgetter, "AutoRooterGetterSetter getter");
|
||||
if ((rooter->attrs & JSPROP_SETTER) && *rooter->psetter)
|
||||
MarkObjectRoot(trc, (JSObject**) rooter->psetter, "AutoRooterGetterSetter setter");
|
||||
return;
|
||||
}
|
||||
|
||||
case REGEXPSTATICS: {
|
||||
RegExpStatics::AutoRooter *rooter = static_cast<RegExpStatics::AutoRooter *>(this);
|
||||
rooter->trace(trc);
|
||||
return;
|
||||
}
|
||||
|
||||
case HASHABLEVALUE: {
|
||||
/*
|
||||
HashableValue::AutoRooter *rooter = static_cast<HashableValue::AutoRooter *>(this);
|
||||
@ -625,6 +578,10 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
case JSONPARSER:
|
||||
static_cast<js::JSONParser *>(this)->trace(trc);
|
||||
return;
|
||||
|
||||
case CUSTOM:
|
||||
static_cast<JS::CustomAutoRooter *>(this)->trace(trc);
|
||||
return;
|
||||
}
|
||||
|
||||
JS_ASSERT(tag_ >= 0);
|
||||
@ -648,18 +605,34 @@ AutoGCRooter::traceAllWrappers(JSTracer *trc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegExpStatics::AutoRooter::trace(JSTracer *trc)
|
||||
/* static */ void
|
||||
JS::CustomAutoRooter::traceObject(JSTracer *trc, JSObject **thingp, const char *name)
|
||||
{
|
||||
if (statics->matchesInput)
|
||||
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->matchesInput),
|
||||
"RegExpStatics::AutoRooter matchesInput");
|
||||
if (statics->lazySource)
|
||||
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->lazySource),
|
||||
"RegExpStatics::AutoRooter lazySource");
|
||||
if (statics->pendingInput)
|
||||
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->pendingInput),
|
||||
"RegExpStatics::AutoRooter pendingInput");
|
||||
MarkObjectRoot(trc, thingp, name);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JS::CustomAutoRooter::traceScript(JSTracer *trc, JSScript **thingp, const char *name)
|
||||
{
|
||||
MarkScriptRoot(trc, thingp, name);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JS::CustomAutoRooter::traceString(JSTracer *trc, JSString **thingp, const char *name)
|
||||
{
|
||||
MarkStringRoot(trc, thingp, name);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JS::CustomAutoRooter::traceId(JSTracer *trc, jsid *thingp, const char *name)
|
||||
{
|
||||
MarkIdRoot(trc, thingp, name);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JS::CustomAutoRooter::traceValue(JSTracer *trc, JS::Value *thingp, const char *name)
|
||||
{
|
||||
MarkValueRoot(trc, thingp, name);
|
||||
}
|
||||
|
||||
void
|
||||
@ -668,6 +641,14 @@ HashableValue::AutoRooter::trace(JSTracer *trc)
|
||||
MarkValueRoot(trc, reinterpret_cast<Value*>(&v->value), "HashableValue::AutoRooter");
|
||||
}
|
||||
|
||||
void
|
||||
StackShape::AutoRooter::trace(JSTracer *trc)
|
||||
{
|
||||
if (shape->base)
|
||||
MarkBaseShapeRoot(trc, (BaseShape**) &shape->base, "StackShape::AutoRooter base");
|
||||
MarkIdRoot(trc, (jsid*) &shape->propid, "StackShape::AutoRooter id");
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
|
||||
{
|
||||
|
@ -118,32 +118,26 @@ class JS_PUBLIC_API(AutoGCRooter) {
|
||||
SHAPEVECTOR = -4, /* js::AutoShapeVector */
|
||||
IDARRAY = -6, /* js::AutoIdArray */
|
||||
DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */
|
||||
// UNUSED -8
|
||||
// UNUSED -9
|
||||
OBJECT = -10, /* js::AutoObjectRooter */
|
||||
ID = -11, /* js::AutoIdRooter */
|
||||
VALVECTOR = -12, /* js::AutoValueVector */
|
||||
DESCRIPTOR = -13, /* js::AutoPropertyDescriptorRooter */
|
||||
STRING = -14, /* js::AutoStringRooter */
|
||||
IDVECTOR = -15, /* js::AutoIdVector */
|
||||
OBJVECTOR = -16, /* js::AutoObjectVector */
|
||||
STRINGVECTOR =-17, /* js::AutoStringVector */
|
||||
SCRIPTVECTOR =-18, /* js::AutoScriptVector */
|
||||
PROPDESC = -19, /* js::PropDesc::AutoRooter */
|
||||
STACKSHAPE = -21, /* js::StackShape::AutoRooter */
|
||||
STACKBASESHAPE=-22,/* js::StackBaseShape::AutoRooter */
|
||||
GETTERSETTER =-24, /* js::AutoRooterGetterSetter */
|
||||
REGEXPSTATICS=-25, /* js::RegExpStatics::AutoRooter */
|
||||
NAMEVECTOR = -26, /* js::AutoNameVector */
|
||||
HASHABLEVALUE=-27,
|
||||
IONMASM = -28, /* js::ion::MacroAssembler */
|
||||
IONALLOC = -29, /* js::ion::AutoTempAllocatorRooter */
|
||||
WRAPVECTOR = -30, /* js::AutoWrapperVector */
|
||||
WRAPPER = -31, /* js::AutoWrapperRooter */
|
||||
OBJOBJHASHMAP=-32, /* js::AutoObjectObjectHashMap */
|
||||
OBJU32HASHMAP=-33, /* js::AutoObjectUnsigned32HashMap */
|
||||
OBJHASHSET = -34, /* js::AutoObjectHashSet */
|
||||
JSONPARSER = -35 /* js::JSONParser */
|
||||
OBJECT = -8, /* js::AutoObjectRooter */
|
||||
ID = -9, /* js::AutoIdRooter */
|
||||
VALVECTOR = -10, /* js::AutoValueVector */
|
||||
DESCRIPTOR = -11, /* js::AutoPropertyDescriptorRooter */
|
||||
STRING = -12, /* js::AutoStringRooter */
|
||||
IDVECTOR = -13, /* js::AutoIdVector */
|
||||
OBJVECTOR = -14, /* js::AutoObjectVector */
|
||||
STRINGVECTOR =-15, /* js::AutoStringVector */
|
||||
SCRIPTVECTOR =-16, /* js::AutoScriptVector */
|
||||
NAMEVECTOR = -17, /* js::AutoNameVector */
|
||||
HASHABLEVALUE=-18, /* js::HashableValue */
|
||||
IONMASM = -19, /* js::ion::MacroAssembler */
|
||||
IONALLOC = -20, /* js::ion::AutoTempAllocatorRooter */
|
||||
WRAPVECTOR = -21, /* js::AutoWrapperVector */
|
||||
WRAPPER = -22, /* js::AutoWrapperRooter */
|
||||
OBJOBJHASHMAP=-23, /* js::AutoObjectObjectHashMap */
|
||||
OBJU32HASHMAP=-24, /* js::AutoObjectUnsigned32HashMap */
|
||||
OBJHASHSET = -25, /* js::AutoObjectHashSet */
|
||||
JSONPARSER = -26, /* js::JSONParser */
|
||||
CUSTOM = -27 /* js::CustomAutoRooter */
|
||||
};
|
||||
|
||||
private:
|
||||
@ -667,6 +661,35 @@ class AutoScriptVector : public AutoVectorRooter<JSScript *>
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/*
|
||||
* Cutsom rooting behavior for internal and external clients.
|
||||
*/
|
||||
class JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
|
||||
{
|
||||
public:
|
||||
explicit CustomAutoRooter(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, CUSTOM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
protected:
|
||||
/* Supplied by derived class to trace roots. */
|
||||
virtual void trace(JSTracer *trc) = 0;
|
||||
|
||||
/* Methods for trace() to call to mark roots, for external clients. */
|
||||
static void traceObject(JSTracer *trc, JSObject **thingp, const char *name);
|
||||
static void traceScript(JSTracer *trc, JSScript **thingp, const char *name);
|
||||
static void traceString(JSTracer *trc, JSString **thingp, const char *name);
|
||||
static void traceId(JSTracer *trc, jsid *thingp, const char *name);
|
||||
static void traceValue(JSTracer *trc, JS::Value *thingp, const char *name);
|
||||
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/* Returns true if |v| is considered an acceptable this-value. */
|
||||
typedef bool (*IsAcceptableThis)(const Value &v);
|
||||
|
||||
|
@ -294,19 +294,24 @@ struct PropDesc {
|
||||
bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
|
||||
PropDesc *wrappedDesc) const;
|
||||
|
||||
class AutoRooter : private AutoGCRooter
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, PropDesc *pd_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, PROPDESC), pd(pd_), skip(cx, pd_)
|
||||
: CustomAutoRooter(cx), pd(pd_), skip(cx, pd_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc) {
|
||||
traceValue(trc, &pd->pd_, "PropDesc::AutoRooter pd");
|
||||
traceValue(trc, &pd->value_, "PropDesc::AutoRooter value");
|
||||
traceValue(trc, &pd->get_, "PropDesc::AutoRooter get");
|
||||
traceValue(trc, &pd->set_, "PropDesc::AutoRooter set");
|
||||
}
|
||||
|
||||
PropDesc *pd;
|
||||
SkipRoot skip;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
@ -150,20 +150,32 @@ class RegExpStatics
|
||||
|
||||
/* PreserveRegExpStatics helpers. */
|
||||
|
||||
class AutoRooter : private AutoGCRooter
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, RegExpStatics *statics_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, REGEXPSTATICS), statics(statics_), skip(cx, statics_)
|
||||
: CustomAutoRooter(cx), statics(statics_), skip(cx, statics_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc) {
|
||||
if (statics->matchesInput) {
|
||||
traceString(trc, reinterpret_cast<JSString**>(&statics->matchesInput),
|
||||
"RegExpStatics::AutoRooter matchesInput");
|
||||
}
|
||||
if (statics->lazySource) {
|
||||
traceString(trc, reinterpret_cast<JSString**>(&statics->lazySource),
|
||||
"RegExpStatics::AutoRooter lazySource");
|
||||
}
|
||||
if (statics->pendingInput) {
|
||||
traceString(trc, reinterpret_cast<JSString**>(&statics->pendingInput),
|
||||
"RegExpStatics::AutoRooter pendingInput");
|
||||
}
|
||||
}
|
||||
|
||||
RegExpStatics *statics;
|
||||
SkipRoot skip;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
@ -427,19 +427,26 @@ struct StackBaseShape
|
||||
static inline HashNumber hash(const StackBaseShape *lookup);
|
||||
static inline bool match(RawUnownedBaseShape key, const StackBaseShape *lookup);
|
||||
|
||||
class AutoRooter : private AutoGCRooter
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, const StackBaseShape *base_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, STACKBASESHAPE), base(base_), skip(cx, base_)
|
||||
: CustomAutoRooter(cx), base(base_), skip(cx, base_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc) {
|
||||
if (base->parent)
|
||||
traceObject(trc, (JSObject**)&base->parent, "StackBaseShape::AutoRooter parent");
|
||||
if ((base->flags & BaseShape::HAS_GETTER_OBJECT) && base->rawGetter)
|
||||
traceObject(trc, (JSObject**)&base->rawGetter, "StackBaseShape::AutoRooter getter");
|
||||
if ((base->flags & BaseShape::HAS_SETTER_OBJECT) && base->rawSetter)
|
||||
traceObject(trc, (JSObject**)&base->rawSetter, "StackBaseShape::AutoRooter setter");
|
||||
}
|
||||
|
||||
const StackBaseShape *base;
|
||||
SkipRoot skip;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
@ -851,22 +858,27 @@ class Shape : public js::gc::Cell
|
||||
|
||||
class AutoRooterGetterSetter
|
||||
{
|
||||
class Inner : private AutoGCRooter
|
||||
class Inner : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
Inner(JSContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter_, StrictPropertyOp *psetter_)
|
||||
: AutoGCRooter(cx, GETTERSETTER), attrs(attrs),
|
||||
pgetter(pgetter_), psetter(psetter_),
|
||||
getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
|
||||
: CustomAutoRooter(cx), attrs(attrs),
|
||||
pgetter(pgetter_), psetter(psetter_),
|
||||
getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
|
||||
{
|
||||
JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
|
||||
JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc) {
|
||||
if ((attrs & JSPROP_GETTER) && *pgetter)
|
||||
traceObject(trc, (JSObject**) pgetter, "AutoRooterGetterSetter getter");
|
||||
if ((attrs & JSPROP_SETTER) && *psetter)
|
||||
traceObject(trc, (JSObject**) psetter, "AutoRooterGetterSetter setter");
|
||||
}
|
||||
|
||||
uint8_t attrs;
|
||||
PropertyOp *pgetter;
|
||||
StrictPropertyOp *psetter;
|
||||
@ -883,8 +895,6 @@ class AutoRooterGetterSetter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
mozilla::Maybe<Inner> inner;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
@ -1006,19 +1016,19 @@ struct StackShape
|
||||
|
||||
inline HashNumber hash() const;
|
||||
|
||||
class AutoRooter : private AutoGCRooter
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, const StackShape *shape_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, STACKSHAPE), shape(shape_), skip(cx, shape_)
|
||||
: CustomAutoRooter(cx), shape(shape_), skip(cx, shape_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc);
|
||||
|
||||
const StackShape *shape;
|
||||
SkipRoot skip;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
Loading…
Reference in New Issue
Block a user