diff --git a/js/src/jsobj.h b/js/src/jsobj.h index a709d03fc28..b9366d941ba 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -412,10 +412,6 @@ struct JSObject : public js::ObjectImpl friend struct js::GCMarker; friend class js::NewObjectCache; -#ifdef DEBUG - void checkShapeConsistency(); -#endif - /* Make the type object to use for LAZY_TYPE objects. */ void makeLazyType(JSContext *cx); diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index c79011f433a..be61992445a 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -512,76 +512,6 @@ NormalizeGetterAndSetter(JSContext *cx, JSObject *obj, return true; } -#ifdef DEBUG -# define CHECK_SHAPE_CONSISTENCY(obj) obj->checkShapeConsistency() - -void -JSObject::checkShapeConsistency() -{ - static int throttle = -1; - if (throttle < 0) { - if (const char *var = getenv("JS_CHECK_SHAPE_THROTTLE")) - throttle = atoi(var); - if (throttle < 0) - throttle = 0; - } - if (throttle == 0) - return; - - JS_ASSERT(isNative()); - - Shape *shape = lastProperty(); - Shape *prev = NULL; - - if (inDictionaryMode()) { - JS_ASSERT(shape->hasTable()); - - PropertyTable &table = shape->table(); - for (uint32_t fslot = table.freelist; fslot != SHAPE_INVALID_SLOT; - fslot = getSlot(fslot).toPrivateUint32()) { - JS_ASSERT(fslot < slotSpan()); - } - - for (int n = throttle; --n >= 0 && shape->parent; shape = shape->parent) { - JS_ASSERT_IF(shape != lastProperty(), !shape->hasTable()); - - Shape **spp = table.search(shape->propid(), false); - JS_ASSERT(SHAPE_FETCH(spp) == shape); - } - - shape = lastProperty(); - for (int n = throttle; --n >= 0 && shape; shape = shape->parent) { - JS_ASSERT_IF(shape->slot() != SHAPE_INVALID_SLOT, shape->slot() < slotSpan()); - if (!prev) { - JS_ASSERT(shape == lastProperty()); - JS_ASSERT(shape->listp == &shape_); - } else { - JS_ASSERT(shape->listp == &prev->parent); - } - prev = shape; - } - } else { - for (int n = throttle; --n >= 0 && shape->parent; shape = shape->parent) { - if (shape->hasTable()) { - PropertyTable &table = shape->table(); - JS_ASSERT(shape->parent); - for (Shape::Range r(shape); !r.empty(); r.popFront()) { - Shape **spp = table.search(r.front().propid(), false); - JS_ASSERT(SHAPE_FETCH(spp) == &r.front()); - } - } - if (prev) { - JS_ASSERT(prev->maybeSlot() >= shape->maybeSlot()); - shape->kids.checkConsistency(prev); - } - prev = shape; - } - } -} -#else -# define CHECK_SHAPE_CONSISTENCY(obj) ((void)0) -#endif - Shape * JSObject::addProperty(JSContext *cx, jsid id, PropertyOp getter, StrictPropertyOp setter, @@ -680,11 +610,11 @@ JSObject::addPropertyInternal(JSContext *cx, jsid id, shape->parent->handoffTableTo(shape); } - CHECK_SHAPE_CONSISTENCY(self); + self->checkShapeConsistency(); return shape; } - CHECK_SHAPE_CONSISTENCY(self); + self->checkShapeConsistency(); return NULL; } @@ -841,7 +771,7 @@ JSObject::putProperty(JSContext *cx, jsid id, Shape *newShape = self->getChildProperty(cx, shape->parent, child); if (!newShape) { - CHECK_SHAPE_CONSISTENCY(self); + self->checkShapeConsistency(); return NULL; } @@ -860,7 +790,7 @@ JSObject::putProperty(JSContext *cx, jsid id, JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals); } - CHECK_SHAPE_CONSISTENCY(self); + self->checkShapeConsistency(); return shape; } @@ -904,7 +834,7 @@ JSObject::changeProperty(JSContext *cx, Shape *shape, unsigned attrs, unsigned m Shape *newShape = putProperty(cx, shape->propid(), getter, setter, shape->maybeSlot(), attrs, shape->flags, shape->maybeShortid()); - CHECK_SHAPE_CONSISTENCY(this); + checkShapeConsistency(); return newShape; } @@ -1021,7 +951,7 @@ JSObject::removeProperty(JSContext *cx, jsid id) self->removeLastProperty(cx); } - CHECK_SHAPE_CONSISTENCY(self); + self->checkShapeConsistency(); return true; } @@ -1043,7 +973,7 @@ JSObject::clear(JSContext *cx) JS_ALWAYS_TRUE(setLastProperty(cx, shape)); JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals); - CHECK_SHAPE_CONSISTENCY(this); + checkShapeConsistency(); } void diff --git a/js/src/vm/ObjectImpl.cpp b/js/src/vm/ObjectImpl.cpp index 4962e417a1d..a5660f5b864 100644 --- a/js/src/vm/ObjectImpl.cpp +++ b/js/src/vm/ObjectImpl.cpp @@ -25,6 +25,72 @@ static ObjectElements emptyElementsHeader(0, 0); HeapSlot *js::emptyObjectElements = reinterpret_cast(uintptr_t(&emptyElementsHeader) + sizeof(ObjectElements)); +#ifdef DEBUG +void +js::ObjectImpl::checkShapeConsistency() +{ + static int throttle = -1; + if (throttle < 0) { + if (const char *var = getenv("JS_CHECK_SHAPE_THROTTLE")) + throttle = atoi(var); + if (throttle < 0) + throttle = 0; + } + if (throttle == 0) + return; + + MOZ_ASSERT(isNative()); + + Shape *shape = lastProperty(); + Shape *prev = NULL; + + if (inDictionaryMode()) { + MOZ_ASSERT(shape->hasTable()); + + PropertyTable &table = shape->table(); + for (uint32_t fslot = table.freelist; fslot != SHAPE_INVALID_SLOT; + fslot = getSlot(fslot).toPrivateUint32()) { + MOZ_ASSERT(fslot < slotSpan()); + } + + for (int n = throttle; --n >= 0 && shape->parent; shape = shape->parent) { + MOZ_ASSERT_IF(shape != lastProperty(), !shape->hasTable()); + + Shape **spp = table.search(shape->propid(), false); + MOZ_ASSERT(SHAPE_FETCH(spp) == shape); + } + + shape = lastProperty(); + for (int n = throttle; --n >= 0 && shape; shape = shape->parent) { + MOZ_ASSERT_IF(shape->slot() != SHAPE_INVALID_SLOT, shape->slot() < slotSpan()); + if (!prev) { + MOZ_ASSERT(shape == lastProperty()); + MOZ_ASSERT(shape->listp == &shape_); + } else { + MOZ_ASSERT(shape->listp == &prev->parent); + } + prev = shape; + } + } else { + for (int n = throttle; --n >= 0 && shape->parent; shape = shape->parent) { + if (shape->hasTable()) { + PropertyTable &table = shape->table(); + MOZ_ASSERT(shape->parent); + for (Shape::Range r(shape); !r.empty(); r.popFront()) { + Shape **spp = table.search(r.front().propid(), false); + MOZ_ASSERT(SHAPE_FETCH(spp) == &r.front()); + } + } + if (prev) { + MOZ_ASSERT(prev->maybeSlot() >= shape->maybeSlot()); + shape->kids.checkConsistency(prev); + } + prev = shape; + } + } +} +#endif + void js::ObjectImpl::initSlotRange(size_t start, const Value *vector, size_t length) { diff --git a/js/src/vm/ObjectImpl.h b/js/src/vm/ObjectImpl.h index 70776eb76b6..93daa5f261e 100644 --- a/js/src/vm/ObjectImpl.h +++ b/js/src/vm/ObjectImpl.h @@ -155,6 +155,12 @@ class ObjectImpl : public gc::Cell HeapSlot *slots; /* Slots for object properties. */ HeapSlot *elements; /* Slots for object elements. */ +#ifdef DEBUG + void checkShapeConsistency(); +#else + void checkShapeConsistency() { } +#endif + private: static void staticAsserts() { MOZ_STATIC_ASSERT(sizeof(ObjectImpl) == sizeof(shadow::Object),