Bug 506786 - JSScope::trace method. r=brendan.

This commit is contained in:
Jason Orendorff 2009-07-28 04:00:35 -05:00
parent e7f2714ea1
commit eb14203c0c
6 changed files with 57 additions and 58 deletions

View File

@ -4058,13 +4058,13 @@ prop_iter_trace(JSTracer *trc, JSObject *obj)
/* Native case: just mark the next property to visit. */
sprop = (JSScopeProperty *) JSVAL_TO_PRIVATE(v);
if (sprop)
TRACE_SCOPE_PROPERTY(trc, sprop);
sprop->trace(trc);
} else {
/* Non-native case: mark each id in the JSIdArray private. */
ida = (JSIdArray *) JSVAL_TO_PRIVATE(v);
for (i = 0, n = ida->length; i < n; i++) {
id = ida->vector[i];
TRACE_ID(trc, id);
js_TraceId(trc, id);
}
}
}

View File

@ -434,7 +434,7 @@ js_TraceWatchPoints(JSTracer *trc, JSObject *obj)
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (wp->object == obj) {
TRACE_SCOPE_PROPERTY(trc, wp->sprop);
wp->sprop->trace(trc);
if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) {
JS_CALL_OBJECT_TRACER(trc, js_CastAsObject(wp->setter),
"wp->setter");

View File

@ -3043,7 +3043,7 @@ js_TraceContext(JSTracer *trc, JSContext *acx)
tvr->u.trace(trc, tvr);
break;
case JSTVU_SPROP:
TRACE_SCOPE_PROPERTY(trc, tvr->u.sprop);
tvr->u.sprop->trace(trc);
break;
case JSTVU_WEAK_ROOTS:
TraceWeakRoots(trc, tvr->u.weakRoots);

View File

@ -5085,7 +5085,7 @@ js_TraceNativeEnumerators(JSTracer *trc)
cursor = ne->ids;
end = cursor + ne->length;
do {
TRACE_ID(trc, *cursor);
js_TraceId(trc, *cursor);
} while (++cursor != end);
} else if (doGC) {
js_RemoveAsGCBytes(rt, NativeEnumeratorSize(ne->length));
@ -5748,7 +5748,6 @@ js_TraceObject(JSTracer *trc, JSObject *obj)
{
JSContext *cx;
JSScope *scope;
JSScopeProperty *sprop;
JSClass *clasp;
size_t nslots, i;
jsval v;
@ -5772,49 +5771,7 @@ js_TraceObject(JSTracer *trc, JSObject *obj)
MeterEntryCount(scope->entryCount);
#endif
sprop = scope->lastProp;
uint8 regenFlag = cx->runtime->gcRegenShapesScopeFlag;
if (IS_GC_MARKING_TRACER(trc) &&
cx->runtime->gcRegenShapes &&
scope->hasRegenFlag(regenFlag)) {
/*
* Either scope has its own shape, which must be regenerated, or it
* must have the same shape as its lastProp.
*/
uint32 shape;
if (sprop) {
if (!(sprop->flags & SPROP_FLAG_SHAPE_REGEN)) {
sprop->shape = js_RegenerateShapeForGC(cx);
sprop->flags |= SPROP_FLAG_SHAPE_REGEN;
}
shape = sprop->shape;
}
if (!sprop || scope->hasOwnShape()) {
shape = js_RegenerateShapeForGC(cx);
JS_ASSERT_IF(sprop, shape != sprop->shape);
}
scope->shape = shape;
scope->flags ^= JSScope::SHAPE_REGEN;
/* Also regenerate the shapes of empty scopes, in case they are not shared. */
for (JSScope *empty = scope->emptyScope;
empty && empty->hasRegenFlag(regenFlag);
empty = empty->emptyScope) {
empty->shape = js_RegenerateShapeForGC(cx);
empty->flags ^= JSScope::SHAPE_REGEN;
}
}
if (sprop) {
JS_ASSERT(scope->has(sprop));
/* Trace scope's property tree ancestor line. */
do {
if (scope->hadMiddleDelete() && !scope->has(sprop))
continue;
TRACE_SCOPE_PROPERTY(trc, sprop);
} while ((sprop = sprop->parent) != NULL);
}
scope->trace(trc);
if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList))
js_TraceWatchPoints(trc, obj);

View File

@ -1649,7 +1649,7 @@ JSScopeProperty::trace(JSTracer *trc)
{
if (IS_GC_MARKING_TRACER(trc))
flags |= SPROP_MARK;
TRACE_ID(trc, id);
js_TraceId(trc, id);
#if JS_HAS_GETTER_SETTER
if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {

View File

@ -265,6 +265,8 @@ struct JSScope {
void extend(JSContext *cx, JSScopeProperty *sprop);
void trace(JSTracer *trc);
void brandingShapeChange(JSContext *cx, uint32 slot, jsval v);
void deletingShapeChange(JSContext *cx, JSScopeProperty *sprop);
void methodShapeChange(JSContext *cx, uint32 slot, jsval toval);
@ -501,6 +503,54 @@ JSScope::extend(JSContext *cx, JSScopeProperty *sprop)
lastProp = sprop;
}
inline void
JSScope::trace(JSTracer *trc)
{
JSContext *cx = trc->context;
JSScopeProperty *sprop = lastProp;
uint8 regenFlag = cx->runtime->gcRegenShapesScopeFlag;
if (IS_GC_MARKING_TRACER(trc) && cx->runtime->gcRegenShapes && hasRegenFlag(regenFlag)) {
/*
* Either this scope has its own shape, which must be regenerated, or
* it must have the same shape as lastProp.
*/
uint32 newShape;
if (sprop) {
if (!(sprop->flags & SPROP_FLAG_SHAPE_REGEN)) {
sprop->shape = js_RegenerateShapeForGC(cx);
sprop->flags |= SPROP_FLAG_SHAPE_REGEN;
}
newShape = sprop->shape;
}
if (!sprop || hasOwnShape()) {
newShape = js_RegenerateShapeForGC(cx);
JS_ASSERT_IF(sprop, newShape != sprop->shape);
}
shape = newShape;
flags ^= JSScope::SHAPE_REGEN;
/* Also regenerate the shapes of empty scopes, in case they are not shared. */
for (JSScope *empty = emptyScope;
empty && empty->hasRegenFlag(regenFlag);
empty = empty->emptyScope) {
empty->shape = js_RegenerateShapeForGC(cx);
empty->flags ^= JSScope::SHAPE_REGEN;
}
}
if (sprop) {
JS_ASSERT(has(sprop));
/* Trace scope's property tree ancestor line. */
do {
if (hadMiddleDelete() && !has(sprop))
continue;
sprop->trace(trc);
} while ((sprop = sprop->parent) != NULL);
}
}
static JS_INLINE bool
js_GetSprop(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, jsval* vp)
{
@ -553,14 +603,6 @@ js_SetSprop(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, jsval* vp)
extern JSScope *
js_GetMutableScope(JSContext *cx, JSObject *obj);
/*
* These macros used to inline short code sequences, but they grew over time.
* We retain them for internal backward compatibility, and in case one or both
* ever shrink to inline-able size.
*/
#define TRACE_ID(trc, id) js_TraceId(trc, id)
#define TRACE_SCOPE_PROPERTY(trc, sprop) sprop->trace(trc)
extern void
js_TraceId(JSTracer *trc, jsid id);