Bug 727135 - Make jsid marking interfaces indirect; r=billm

This will allow the GC to move jsid referenced objects.
This commit is contained in:
Terrence Cole 2012-02-17 17:27:37 -08:00
Родитель 4d7dd5aa95
Коммит 156933f7b3
10 изменённых файлов: 52 добавлений и 49 удалений

Просмотреть файл

@ -406,6 +406,7 @@ class HeapId
bool operator!=(jsid id) const { return value != id; } bool operator!=(jsid id) const { return value != id; }
jsid get() const { return value; } jsid get() const { return value; }
jsid *unsafeGet() { return &value; }
operator jsid() const { return value; } operator jsid() const { return value; }
private: private:

Просмотреть файл

@ -177,7 +177,7 @@ JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc)
JS_FRIEND_API(void) JS_FRIEND_API(void)
JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape) JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape)
{ {
MarkCycleCollectorChildren(trc, (const Shape *)shape); MarkCycleCollectorChildren(trc, (Shape *)shape);
} }
AutoPreserveCompartment::AutoPreserveCompartment(JSContext *cx AutoPreserveCompartment::AutoPreserveCompartment(JSContext *cx

Просмотреть файл

@ -2266,7 +2266,7 @@ AutoGCRooter::trace(JSTracer *trc)
return; return;
case ID: case ID:
MarkIdRoot(trc, static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_"); MarkIdRoot(trc, &static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_");
return; return;
case VALVECTOR: { case VALVECTOR: {

Просмотреть файл

@ -61,7 +61,7 @@ static inline void
PushMarkStack(GCMarker *gcmarker, JSScript *thing); PushMarkStack(GCMarker *gcmarker, JSScript *thing);
static inline void static inline void
PushMarkStack(GCMarker *gcmarker, const Shape *thing); PushMarkStack(GCMarker *gcmarker, Shape *thing);
static inline void static inline void
PushMarkStack(GCMarker *gcmarker, JSString *thing); PushMarkStack(GCMarker *gcmarker, JSString *thing);
@ -264,23 +264,28 @@ MarkGCThingRoot(JSTracer *trc, void *thing, const char *name)
/*** ID Marking ***/ /*** ID Marking ***/
static inline void static inline void
MarkIdInternal(JSTracer *trc, const jsid &id) MarkIdInternal(JSTracer *trc, jsid *id)
{ {
if (JSID_IS_STRING(id)) if (JSID_IS_STRING(*id)) {
MarkInternal(trc, JSID_TO_STRING(id)); JSString *str = JSID_TO_STRING(*id);
else if (JS_UNLIKELY(JSID_IS_OBJECT(id))) MarkInternal(trc, str);
MarkInternal(trc, JSID_TO_OBJECT(id)); *id = ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
} else if (JS_UNLIKELY(JSID_IS_OBJECT(*id))) {
JSObject *obj = JSID_TO_OBJECT(*id);
MarkInternal(trc, obj);
*id = OBJECT_TO_JSID(obj);
}
} }
void void
MarkId(JSTracer *trc, const HeapId &id, const char *name) MarkId(JSTracer *trc, HeapId *id, const char *name)
{ {
JS_SET_TRACING_NAME(trc, name); JS_SET_TRACING_NAME(trc, name);
MarkIdInternal(trc, id); MarkIdInternal(trc, id->unsafeGet());
} }
void void
MarkIdRoot(JSTracer *trc, const jsid &id, const char *name) MarkIdRoot(JSTracer *trc, jsid *id, const char *name)
{ {
JS_ROOT_MARKING_ASSERT(trc); JS_ROOT_MARKING_ASSERT(trc);
JS_SET_TRACING_NAME(trc, name); JS_SET_TRACING_NAME(trc, name);
@ -292,7 +297,7 @@ MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name)
{ {
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
JS_SET_TRACING_INDEX(trc, name, i); JS_SET_TRACING_INDEX(trc, name, i);
MarkIdInternal(trc, vec[i]); MarkIdInternal(trc, vec[i].unsafeGet());
} }
} }
@ -302,7 +307,7 @@ MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
JS_ROOT_MARKING_ASSERT(trc); JS_ROOT_MARKING_ASSERT(trc);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
JS_SET_TRACING_INDEX(trc, name, i); JS_SET_TRACING_INDEX(trc, name, i);
MarkIdInternal(trc, vec[i]); MarkIdInternal(trc, &vec[i]);
} }
} }
@ -364,13 +369,6 @@ MarkObject(JSTracer *trc, const HeapPtr<GlobalObject, JSScript *> &thing, const
MarkInternal(trc, thing.get()); MarkInternal(trc, thing.get());
} }
void
MarkShape(JSTracer *trc, HeapPtr<const Shape> *thing, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkInternal(trc, const_cast<Shape *>(thing->get()));
}
void void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name) MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
{ {
@ -460,10 +458,10 @@ PushMarkStack(GCMarker *gcmarker, JSScript *thing)
} }
static void static void
ScanShape(GCMarker *gcmarker, const Shape *shape); ScanShape(GCMarker *gcmarker, Shape *shape);
static void static void
PushMarkStack(GCMarker *gcmarker, const Shape *thing) PushMarkStack(GCMarker *gcmarker, Shape *thing)
{ {
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing); JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
@ -486,12 +484,12 @@ PushMarkStack(GCMarker *gcmarker, BaseShape *thing)
} }
static void static void
ScanShape(GCMarker *gcmarker, const Shape *shape) ScanShape(GCMarker *gcmarker, Shape *shape)
{ {
restart: restart:
PushMarkStack(gcmarker, shape->base()); PushMarkStack(gcmarker, shape->base());
jsid id = shape->maybePropid(); const HeapId &id = shape->propidRef();
if (JSID_IS_STRING(id)) if (JSID_IS_STRING(id))
PushMarkStack(gcmarker, JSID_TO_STRING(id)); PushMarkStack(gcmarker, JSID_TO_STRING(id));
else if (JS_UNLIKELY(JSID_IS_OBJECT(id))) else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
@ -712,7 +710,7 @@ static void
MarkChildren(JSTracer *trc, Shape *shape) MarkChildren(JSTracer *trc, Shape *shape)
{ {
MarkBaseShapeUnbarriered(trc, shape->base(), "base"); MarkBaseShapeUnbarriered(trc, shape->base(), "base");
MarkId(trc, shape->maybePropid(), "propid"); MarkId(trc, &shape->propidRef(), "propid");
if (shape->previous()) if (shape->previous())
MarkShape(trc, &shape->previousRef(), "parent"); MarkShape(trc, &shape->previousRef(), "parent");
} }
@ -775,12 +773,12 @@ MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent
* parent pointer will only be marked once. * parent pointer will only be marked once.
*/ */
void void
MarkCycleCollectorChildren(JSTracer *trc, const Shape *shape) MarkCycleCollectorChildren(JSTracer *trc, Shape *shape)
{ {
JSObject *prevParent = NULL; JSObject *prevParent = NULL;
do { do {
MarkCycleCollectorChildren(trc, shape->base(), &prevParent); MarkCycleCollectorChildren(trc, shape->base(), &prevParent);
MarkId(trc, shape->maybePropid(), "propid"); MarkId(trc, &shape->propidRef(), "propid");
shape = shape->previous(); shape = shape->previous();
} while (shape); } while (shape);
} }
@ -823,7 +821,7 @@ MarkChildren(JSTracer *trc, types::TypeObject *type)
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
types::Property *prop = type->getProperty(i); types::Property *prop = type->getProperty(i);
if (prop) if (prop)
MarkId(trc, prop->id, "type_prop"); MarkId(trc, &prop->id, "type_prop");
} }
} }

Просмотреть файл

@ -83,10 +83,10 @@ MarkGCThingRoot(JSTracer *trc, void *thing, const char *name);
/*** ID Marking ***/ /*** ID Marking ***/
void void
MarkId(JSTracer *trc, const HeapId &id, const char *name); MarkId(JSTracer *trc, HeapId *id, const char *name);
void void
MarkIdRoot(JSTracer *trc, const jsid &id, const char *name); MarkIdRoot(JSTracer *trc, jsid *id, const char *name);
void void
MarkIdRange(JSTracer *trc, size_t len, js::HeapId *vec, const char *name); MarkIdRange(JSTracer *trc, size_t len, js::HeapId *vec, const char *name);
@ -116,10 +116,6 @@ MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
/*** Special Cases ***/ /*** Special Cases ***/
/* TypeNewObject contains a HeapPtr<const Shape> that needs a unique cast. */
void
MarkShape(JSTracer *trc, HeapPtr<const Shape> *thing, const char *name);
/* Direct value access used by the write barriers and the methodjit */ /* Direct value access used by the write barriers and the methodjit */
void void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name); MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
@ -144,7 +140,7 @@ MarkChildren(JSTracer *trc, JSObject *obj);
* JS_TraceShapeCycleCollectorChildren. * JS_TraceShapeCycleCollectorChildren.
*/ */
void void
MarkCycleCollectorChildren(JSTracer *trc, const Shape *shape); MarkCycleCollectorChildren(JSTracer *trc, Shape *shape);
void void
PushArena(GCMarker *gcmarker, ArenaHeader *aheader); PushArena(GCMarker *gcmarker, ArenaHeader *aheader);

Просмотреть файл

@ -2618,7 +2618,7 @@ struct types::ObjectTableKey
typedef JSObject * Lookup; typedef JSObject * Lookup;
static inline uint32_t hash(JSObject *obj) { static inline uint32_t hash(JSObject *obj) {
return (uint32_t) (JSID_BITS(obj->lastProperty()->propid()) ^ return (uint32_t) (JSID_BITS(obj->lastProperty()->propid().get()) ^
obj->slotSpan() ^ obj->numFixedSlots() ^ obj->slotSpan() ^ obj->numFixedSlots() ^
((uint32_t)(size_t)obj->getProto() >> 2)); ((uint32_t)(size_t)obj->getProto() >> 2));
} }

Просмотреть файл

@ -668,7 +668,7 @@ struct TypeNewScript
* Shape to use for newly constructed objects. Reflects all definite * Shape to use for newly constructed objects. Reflects all definite
* properties the object will have. * properties the object will have.
*/ */
HeapPtr<const Shape> shape; HeapPtrShape shape;
/* /*
* Order in which properties become initialized. We need this in case a * Order in which properties become initialized. We need this in case a

Просмотреть файл

@ -1062,7 +1062,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
{ {
JS_ASSERT_IF(oldShape != lastProperty(), JS_ASSERT_IF(oldShape != lastProperty(),
inDictionaryMode() && inDictionaryMode() &&
nativeLookup(cx, oldShape->maybePropid()) == oldShape); nativeLookup(cx, oldShape->propidRef()) == oldShape);
JSObject *self = this; JSObject *self = this;
@ -1086,7 +1086,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
PropertyTable &table = self->lastProperty()->table(); PropertyTable &table = self->lastProperty()->table();
Shape **spp = oldShape->isEmptyShape() Shape **spp = oldShape->isEmptyShape()
? NULL ? NULL
: table.search(oldShape->maybePropid(), false); : table.search(oldShape->propidRef(), false);
/* /*
* Splice the new shape into the same position as the old shape, preserving * Splice the new shape into the same position as the old shape, preserving

Просмотреть файл

@ -774,8 +774,12 @@ struct Shape : public js::gc::Cell
slotInfo = slotInfo | ((count + 1) << LINEAR_SEARCHES_SHIFT); slotInfo = slotInfo | ((count + 1) << LINEAR_SEARCHES_SHIFT);
} }
jsid propid() const { JS_ASSERT(!isEmptyShape()); return maybePropid(); } const HeapId &propid() const {
const HeapId &maybePropid() const { JS_ASSERT(!JSID_IS_VOID(propid_)); return propid_; } JS_ASSERT(!isEmptyShape());
JS_ASSERT(!JSID_IS_VOID(propid_));
return propid_;
}
HeapId &propidRef() { JS_ASSERT(!JSID_IS_VOID(propid_)); return propid_; }
int16_t shortid() const { JS_ASSERT(hasShortID()); return maybeShortid(); } int16_t shortid() const { JS_ASSERT(hasShortID()); return maybeShortid(); }
int16_t maybeShortid() const { return shortid_; } int16_t maybeShortid() const { return shortid_; }
@ -999,7 +1003,7 @@ struct StackShape
StackShape(const Shape *shape) StackShape(const Shape *shape)
: base(shape->base()->unowned()), : base(shape->base()->unowned()),
propid(shape->maybePropid()), propid(const_cast<Shape *>(shape)->propidRef()),
slot_(shape->slotInfo & Shape::SLOT_MASK), slot_(shape->slotInfo & Shape::SLOT_MASK),
attrs(shape->attrs), attrs(shape->attrs),
flags(shape->flags), flags(shape->flags),
@ -1095,7 +1099,7 @@ Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
} }
for (Shape *shape = start; shape; shape = shape->parent) { for (Shape *shape = start; shape; shape = shape->parent) {
if (shape->maybePropid() == id) if (shape->propidRef() == id)
return shape; return shape;
} }

Просмотреть файл

@ -210,7 +210,9 @@ WatchpointMap::markIteratively(JSTracer *trc)
const HeapId &id = e.key.id; const HeapId &id = e.key.id;
JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id)); JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id));
MarkId(trc, id, "WatchKey::id"); HeapId tmp(id.get());
MarkId(trc, &tmp, "WatchKey::id");
JS_ASSERT(tmp.get() == id.get());
if (e.value.closure && IsAboutToBeFinalized(e.value.closure)) { if (e.value.closure && IsAboutToBeFinalized(e.value.closure)) {
MarkObject(trc, &e.value.closure, "Watchpoint::closure"); MarkObject(trc, &e.value.closure, "Watchpoint::closure");
@ -226,13 +228,15 @@ WatchpointMap::markAll(JSTracer *trc)
{ {
for (Map::Range r = map.all(); !r.empty(); r.popFront()) { for (Map::Range r = map.all(); !r.empty(); r.popFront()) {
Map::Entry &e = r.front(); Map::Entry &e = r.front();
HeapPtrObject tmp(e.key.object); HeapPtrObject tmpObj(e.key.object);
MarkObject(trc, &tmp, "held Watchpoint object"); MarkObject(trc, &tmpObj, "held Watchpoint object");
JS_ASSERT(tmp == e.key.object); JS_ASSERT(tmpObj == e.key.object);
const HeapId &id = e.key.id; const HeapId &id = e.key.id;
JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id)); JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id));
MarkId(trc, id, "WatchKey::id"); HeapId tmpId(id.get());
MarkId(trc, &tmpId, "WatchKey::id");
JS_ASSERT(tmpId.get() == id.get());
MarkObject(trc, &e.value.closure, "Watchpoint::closure"); MarkObject(trc, &e.value.closure, "Watchpoint::closure");
} }