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

--HG--
extra : rebase_source : ff4fdd39c15223bff4682b8c7b9833922e355999
This commit is contained in:
Jon Coppeard 2013-04-04 10:39:05 +01:00
parent 14361d21a0
commit ed919c3997
6 changed files with 141 additions and 110 deletions

View File

@ -17,4 +17,4 @@
# #
# Modifying this file will now automatically clobber the buildbot machines \o/ # Modifying this file will now automatically clobber the buildbot machines \o/
# #
Bug 820170 requires a clobber on Windows. Bug 855350 broke Windows builds.

View File

@ -530,53 +530,6 @@ AutoGCRooter::trace(JSTracer *trc)
return; 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: { case HASHABLEVALUE: {
/* /*
HashableValue::AutoRooter *rooter = static_cast<HashableValue::AutoRooter *>(this); HashableValue::AutoRooter *rooter = static_cast<HashableValue::AutoRooter *>(this);
@ -625,6 +578,10 @@ AutoGCRooter::trace(JSTracer *trc)
case JSONPARSER: case JSONPARSER:
static_cast<js::JSONParser *>(this)->trace(trc); static_cast<js::JSONParser *>(this)->trace(trc);
return; return;
case CUSTOM:
static_cast<JS::CustomAutoRooter *>(this)->trace(trc);
return;
} }
JS_ASSERT(tag_ >= 0); JS_ASSERT(tag_ >= 0);
@ -648,18 +605,34 @@ AutoGCRooter::traceAllWrappers(JSTracer *trc)
} }
} }
void /* static */ void
RegExpStatics::AutoRooter::trace(JSTracer *trc) JS::CustomAutoRooter::traceObject(JSTracer *trc, JSObject **thingp, const char *name)
{ {
if (statics->matchesInput) MarkObjectRoot(trc, thingp, name);
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->matchesInput), }
"RegExpStatics::AutoRooter matchesInput");
if (statics->lazySource) /* static */ void
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->lazySource), JS::CustomAutoRooter::traceScript(JSTracer *trc, JSScript **thingp, const char *name)
"RegExpStatics::AutoRooter lazySource"); {
if (statics->pendingInput) MarkScriptRoot(trc, thingp, name);
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->pendingInput), }
"RegExpStatics::AutoRooter pendingInput");
/* 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 void
@ -668,6 +641,14 @@ HashableValue::AutoRooter::trace(JSTracer *trc)
MarkValueRoot(trc, reinterpret_cast<Value*>(&v->value), "HashableValue::AutoRooter"); 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 void
js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots) js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
{ {

View File

@ -118,32 +118,26 @@ class JS_PUBLIC_API(AutoGCRooter) {
SHAPEVECTOR = -4, /* js::AutoShapeVector */ SHAPEVECTOR = -4, /* js::AutoShapeVector */
IDARRAY = -6, /* js::AutoIdArray */ IDARRAY = -6, /* js::AutoIdArray */
DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */ DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */
// UNUSED -8 OBJECT = -8, /* js::AutoObjectRooter */
// UNUSED -9 ID = -9, /* js::AutoIdRooter */
OBJECT = -10, /* js::AutoObjectRooter */ VALVECTOR = -10, /* js::AutoValueVector */
ID = -11, /* js::AutoIdRooter */ DESCRIPTOR = -11, /* js::AutoPropertyDescriptorRooter */
VALVECTOR = -12, /* js::AutoValueVector */ STRING = -12, /* js::AutoStringRooter */
DESCRIPTOR = -13, /* js::AutoPropertyDescriptorRooter */ IDVECTOR = -13, /* js::AutoIdVector */
STRING = -14, /* js::AutoStringRooter */ OBJVECTOR = -14, /* js::AutoObjectVector */
IDVECTOR = -15, /* js::AutoIdVector */ STRINGVECTOR =-15, /* js::AutoStringVector */
OBJVECTOR = -16, /* js::AutoObjectVector */ SCRIPTVECTOR =-16, /* js::AutoScriptVector */
STRINGVECTOR =-17, /* js::AutoStringVector */ NAMEVECTOR = -17, /* js::AutoNameVector */
SCRIPTVECTOR =-18, /* js::AutoScriptVector */ HASHABLEVALUE=-18, /* js::HashableValue */
PROPDESC = -19, /* js::PropDesc::AutoRooter */ IONMASM = -19, /* js::ion::MacroAssembler */
STACKSHAPE = -21, /* js::StackShape::AutoRooter */ IONALLOC = -20, /* js::ion::AutoTempAllocatorRooter */
STACKBASESHAPE=-22,/* js::StackBaseShape::AutoRooter */ WRAPVECTOR = -21, /* js::AutoWrapperVector */
GETTERSETTER =-24, /* js::AutoRooterGetterSetter */ WRAPPER = -22, /* js::AutoWrapperRooter */
REGEXPSTATICS=-25, /* js::RegExpStatics::AutoRooter */ OBJOBJHASHMAP=-23, /* js::AutoObjectObjectHashMap */
NAMEVECTOR = -26, /* js::AutoNameVector */ OBJU32HASHMAP=-24, /* js::AutoObjectUnsigned32HashMap */
HASHABLEVALUE=-27, OBJHASHSET = -25, /* js::AutoObjectHashSet */
IONMASM = -28, /* js::ion::MacroAssembler */ JSONPARSER = -26, /* js::JSONParser */
IONALLOC = -29, /* js::ion::AutoTempAllocatorRooter */ CUSTOM = -27 /* js::CustomAutoRooter */
WRAPVECTOR = -30, /* js::AutoWrapperVector */
WRAPPER = -31, /* js::AutoWrapperRooter */
OBJOBJHASHMAP=-32, /* js::AutoObjectObjectHashMap */
OBJU32HASHMAP=-33, /* js::AutoObjectUnsigned32HashMap */
OBJHASHSET = -34, /* js::AutoObjectHashSet */
JSONPARSER = -35 /* js::JSONParser */
}; };
private: private:
@ -667,6 +661,35 @@ class AutoScriptVector : public AutoVectorRooter<JSScript *>
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 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. */ /* Returns true if |v| is considered an acceptable this-value. */
typedef bool (*IsAcceptableThis)(const Value &v); 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, bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
PropDesc *wrappedDesc) const; PropDesc *wrappedDesc) const;
class AutoRooter : private AutoGCRooter class AutoRooter : private JS::CustomAutoRooter
{ {
public: public:
explicit AutoRooter(JSContext *cx, PropDesc *pd_ explicit AutoRooter(JSContext *cx, PropDesc *pd_
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 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; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
friend void AutoGCRooter::trace(JSTracer *trc);
private: 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; PropDesc *pd;
SkipRoot skip; SkipRoot skip;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER

View File

@ -150,20 +150,32 @@ class RegExpStatics
/* PreserveRegExpStatics helpers. */ /* PreserveRegExpStatics helpers. */
class AutoRooter : private AutoGCRooter class AutoRooter : private JS::CustomAutoRooter
{ {
public: public:
explicit AutoRooter(JSContext *cx, RegExpStatics *statics_ explicit AutoRooter(JSContext *cx, RegExpStatics *statics_
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 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; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
friend void AutoGCRooter::trace(JSTracer *trc);
void trace(JSTracer *trc);
private: 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; RegExpStatics *statics;
SkipRoot skip; SkipRoot skip;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER

View File

@ -427,19 +427,26 @@ struct StackBaseShape
static inline HashNumber hash(const StackBaseShape *lookup); static inline HashNumber hash(const StackBaseShape *lookup);
static inline bool match(RawUnownedBaseShape key, const StackBaseShape *lookup); static inline bool match(RawUnownedBaseShape key, const StackBaseShape *lookup);
class AutoRooter : private AutoGCRooter class AutoRooter : private JS::CustomAutoRooter
{ {
public: public:
explicit AutoRooter(JSContext *cx, const StackBaseShape *base_ explicit AutoRooter(JSContext *cx, const StackBaseShape *base_
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 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; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
friend void AutoGCRooter::trace(JSTracer *trc);
private: 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; const StackBaseShape *base;
SkipRoot skip; SkipRoot skip;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
@ -851,22 +858,27 @@ class Shape : public js::gc::Cell
class AutoRooterGetterSetter class AutoRooterGetterSetter
{ {
class Inner : private AutoGCRooter class Inner : private JS::CustomAutoRooter
{ {
public: public:
Inner(JSContext *cx, uint8_t attrs, Inner(JSContext *cx, uint8_t attrs,
PropertyOp *pgetter_, StrictPropertyOp *psetter_) PropertyOp *pgetter_, StrictPropertyOp *psetter_)
: AutoGCRooter(cx, GETTERSETTER), attrs(attrs), : CustomAutoRooter(cx), attrs(attrs),
pgetter(pgetter_), psetter(psetter_), pgetter(pgetter_), psetter(psetter_),
getterRoot(cx, pgetter_), setterRoot(cx, psetter_) getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
{ {
JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter)); JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter)); JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
} }
friend void AutoGCRooter::trace(JSTracer *trc);
private: 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; uint8_t attrs;
PropertyOp *pgetter; PropertyOp *pgetter;
StrictPropertyOp *psetter; StrictPropertyOp *psetter;
@ -883,8 +895,6 @@ class AutoRooterGetterSetter
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
friend void AutoGCRooter::trace(JSTracer *trc);
private: private:
mozilla::Maybe<Inner> inner; mozilla::Maybe<Inner> inner;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
@ -1006,19 +1016,19 @@ struct StackShape
inline HashNumber hash() const; inline HashNumber hash() const;
class AutoRooter : private AutoGCRooter class AutoRooter : private JS::CustomAutoRooter
{ {
public: public:
explicit AutoRooter(JSContext *cx, const StackShape *shape_ explicit AutoRooter(JSContext *cx, const StackShape *shape_
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 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; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
friend void AutoGCRooter::trace(JSTracer *trc);
private: private:
virtual void trace(JSTracer *trc);
const StackShape *shape; const StackShape *shape;
SkipRoot skip; SkipRoot skip;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER