зеркало из https://github.com/mozilla/pjs.git
Bug 727135 - Make jsid marking interfaces indirect; r=billm
This will allow the GC to move jsid referenced objects.
This commit is contained in:
Родитель
4d7dd5aa95
Коммит
156933f7b3
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче