Bug 855350 - GC: Add CustomAutoRooter and use it internally r=terrence

This commit is contained in:
Jon Coppeard 2013-03-27 17:47:01 +00:00
parent c4b1a4ed44
commit 6db07a6d40
5 changed files with 140 additions and 109 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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