diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp index d6f8dcef7a6..9f1b7fb58ec 100644 --- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -49,11 +49,6 @@ #include "jsxml.h" #endif -#include "jsscope.h" -#include "vm/GlobalObject.h" - -#include "jsobjinlines.h" - using namespace js; static ParseNode * diff --git a/js/src/frontend/ParseMaps.cpp b/js/src/frontend/ParseMaps.cpp index 4388191ebda..ab6c345ee4e 100644 --- a/js/src/frontend/ParseMaps.cpp +++ b/js/src/frontend/ParseMaps.cpp @@ -41,8 +41,6 @@ #include "ParseMaps-inl.h" #include "jscompartment.h" -#include "jsobjinlines.h" - using namespace js; void diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index 36d9deed701..42eb956307a 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -44,14 +44,10 @@ #include "jscrashreport.h" #include "jsprf.h" #include "jsprobes.h" -#include "jsscope.h" #include "jsutil.h" #include "prmjtime.h" #include "gc/Statistics.h" -#include "vm/GlobalObject.h" - -#include "jsobjinlines.h" namespace js { namespace gcstats { diff --git a/js/src/jsapi-tests/testArgumentsObject.cpp b/js/src/jsapi-tests/testArgumentsObject.cpp index 359852f50a2..83587c56fbd 100644 --- a/js/src/jsapi-tests/testArgumentsObject.cpp +++ b/js/src/jsapi-tests/testArgumentsObject.cpp @@ -6,8 +6,6 @@ #include "vm/Stack-inl.h" -#include "jsobjinlines.h" - using namespace js; static const char NORMAL_ZERO[] = diff --git a/js/src/jsapi-tests/testBug604087.cpp b/js/src/jsapi-tests/testBug604087.cpp index 63a43c2978c..27b7e0b54aa 100644 --- a/js/src/jsapi-tests/testBug604087.cpp +++ b/js/src/jsapi-tests/testBug604087.cpp @@ -8,8 +8,6 @@ #include "jsobj.h" #include "jswrapper.h" -#include "jsobjinlines.h" - struct OuterWrapper : js::Wrapper { OuterWrapper() : Wrapper(0) {} diff --git a/js/src/jsapi-tests/testConservativeGC.cpp b/js/src/jsapi-tests/testConservativeGC.cpp index d61ead7a2ca..163189bce04 100644 --- a/js/src/jsapi-tests/testConservativeGC.cpp +++ b/js/src/jsapi-tests/testConservativeGC.cpp @@ -1,9 +1,6 @@ #include "tests.h" #include "jsobj.h" #include "vm/String.h" -#include "vm/GlobalObject.h" - -#include "jsobjinlines.h" BEGIN_TEST(testConservativeGC) { diff --git a/js/src/jsapi-tests/testExtendedEq.cpp b/js/src/jsapi-tests/testExtendedEq.cpp index 5915e373b05..8670dfac173 100644 --- a/js/src/jsapi-tests/testExtendedEq.cpp +++ b/js/src/jsapi-tests/testExtendedEq.cpp @@ -7,9 +7,6 @@ #include "tests.h" #include "jsobj.h" -#include "vm/GlobalObject.h" - -#include "jsobjinlines.h" static JSBool my_Equality(JSContext *cx, JSObject *obj, const jsval *, JSBool *bp) diff --git a/js/src/jsapi-tests/testIndexToString.cpp b/js/src/jsapi-tests/testIndexToString.cpp index f240b601ac7..c93410f5955 100644 --- a/js/src/jsapi-tests/testIndexToString.cpp +++ b/js/src/jsapi-tests/testIndexToString.cpp @@ -9,8 +9,6 @@ #include "jsnum.h" #include "jsstr.h" -#include "jsobjinlines.h" - #include "vm/String-inl.h" using namespace mozilla; diff --git a/js/src/jsapi-tests/testXDR.cpp b/js/src/jsapi-tests/testXDR.cpp index 39913e84437..aac6fe0ad26 100644 --- a/js/src/jsapi-tests/testXDR.cpp +++ b/js/src/jsapi-tests/testXDR.cpp @@ -6,10 +6,6 @@ #include "jsscript.h" #include "jsxdrapi.h" -#include "vm/GlobalObject.h" - -#include "jsobjinlines.h" - BEGIN_TEST(testXDR_bug506491) { const char *s = diff --git a/js/src/jsarrayinlines.h b/js/src/jsarrayinlines.h index 965dafffa56..659bfd49999 100644 --- a/js/src/jsarrayinlines.h +++ b/js/src/jsarrayinlines.h @@ -60,12 +60,13 @@ JSObject::ensureDenseArrayInitializedLength(JSContext *cx, uint32 index, uint32 */ JS_ASSERT(index + extra <= getDenseArrayCapacity()); uint32 &initlen = getElementsHeader()->initializedLength; - if (initlen < index) { + if (initlen < index) markDenseArrayNotPacked(cx); - js::InitValueRange(elements + initlen, index - initlen, true); - } - if (initlen < index + extra) + + if (initlen < index + extra) { + js::InitValueRange(elements + initlen, index + extra - initlen, true); initlen = index + extra; + } } inline JSObject::EnsureDenseResult diff --git a/js/src/jsfun.h b/js/src/jsfun.h index c898bf23b8c..dc9a36fb0f1 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -425,16 +425,6 @@ JSFunction::toExtended() const return static_cast(this); } -inline void -JSFunction::initializeExtended() -{ - JS_ASSERT(isExtended()); - - JS_STATIC_ASSERT(JS_ARRAY_LENGTH(toExtended()->extendedSlots) == 2); - toExtended()->extendedSlots[0].init(js::UndefinedValue()); - toExtended()->extendedSlots[1].init(js::UndefinedValue()); -} - extern JSBool js_GetArgsValue(JSContext *cx, js::StackFrame *fp, js::Value *vp); diff --git a/js/src/jsfuninlines.h b/js/src/jsfuninlines.h index b9855f2f515..b1bfd935f90 100644 --- a/js/src/jsfuninlines.h +++ b/js/src/jsfuninlines.h @@ -65,6 +65,16 @@ JSFunction::setEnvironment(JSObject *obj) u.i.env = obj; } +inline void +JSFunction::initializeExtended() +{ + JS_ASSERT(isExtended()); + + JS_STATIC_ASSERT(JS_ARRAY_LENGTH(toExtended()->extendedSlots) == 2); + toExtended()->extendedSlots[0].init(js::UndefinedValue()); + toExtended()->extendedSlots[1].init(js::UndefinedValue()); +} + inline void JSFunction::setJoinable() { diff --git a/js/src/jsgcmark.h b/js/src/jsgcmark.h index 7fe87047516..647136b697f 100644 --- a/js/src/jsgcmark.h +++ b/js/src/jsgcmark.h @@ -82,7 +82,7 @@ void MarkShape(JSTracer *trc, const MarkablePtr &shape, const char *name); void -MarkBaseShapeUnbarriered(JSTracer *trc, const BaseShape *shape, const char *name); +MarkBaseShapeUnbarriered(JSTracer *trc, BaseShape *shape, const char *name); void MarkTypeObjectUnbarriered(JSTracer *trc, types::TypeObject *type, const char *name); diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 878dd3ffb34..d79c44ef971 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -5779,7 +5779,7 @@ JSObject::setNewTypeUnknown(JSContext *cx) * not have the SETS_MARKED_UNKNOWN bit set, so may require a type set * crawl if prototypes of the object change dynamically in the future. */ - TypeObjectSet &table = compartment()->newTypeObjects; + TypeObjectSet &table = cx->compartment->newTypeObjects; if (table.initialized()) { TypeObjectSet::Ptr p = table.lookup(this); if (p) @@ -5818,6 +5818,9 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun) if (type->newScript && type->newScript->fun != fun) type->clearNewScript(cx); + if (cx->compartment->needsBarrier()) + TypeObject::readBarrier(type); + return type; } @@ -5882,6 +5885,10 @@ JSCompartment::getLazyType(JSContext *cx, JSObject *proto) if (p) { TypeObject *type = *p; JS_ASSERT(type->lazy()); + + if (cx->compartment->needsBarrier()) + TypeObject::readBarrier(type); + return type; } diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 596da2450c4..9341ad89cbb 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -876,6 +876,7 @@ struct TypeObject : gc::Cell static inline void writeBarrierPre(TypeObject *type); static inline void writeBarrierPost(TypeObject *type, void *addr); + static inline void readBarrier(TypeObject *type); private: inline uint32 basePropertyCount() const; @@ -1046,9 +1047,7 @@ class TypeScript /* Dynamic types generated at points within this script. */ TypeResult *dynamicList; - TypeScript() { - this->global = (js::GlobalObject *) GLOBAL_MISSING_SCOPE; - } + inline TypeScript(); bool hasScope() { return size_t(global.get()) != GLOBAL_MISSING_SCOPE; } diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index bfcf2aa82e5..9a2fbab6402 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -459,6 +459,12 @@ UseNewTypeAtEntry(JSContext *cx, StackFrame *fp) // Script interface functions ///////////////////////////////////////////////////////////////////// +inline +TypeScript::TypeScript() +{ + this->global = (js::GlobalObject *) GLOBAL_MISSING_SCOPE; +} + /* static */ inline unsigned TypeScript::NumTypeSets(JSScript *script) { @@ -1254,7 +1260,7 @@ inline void TypeObject::writeBarrierPre(TypeObject *type) { #ifdef JSGC_INCREMENTAL - if (!type || type == &js::types::emptyTypeObject) + if (!type) return; JSCompartment *comp = type->compartment(); @@ -1268,6 +1274,17 @@ TypeObject::writeBarrierPost(TypeObject *type, void *addr) { } +inline void +TypeObject::readBarrier(TypeObject *type) +{ +#ifdef JSGC_INCREMENTAL + JSCompartment *comp = type->compartment(); + JS_ASSERT(comp->needsBarrier()); + + MarkTypeObjectUnbarriered(comp->barrierTracer(), type, "read barrier"); +#endif +} + inline void TypeNewScript::writeBarrierPre(TypeNewScript *newScript) { diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 9943c0f5528..bd4a37dab1a 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -686,13 +686,6 @@ CallObjectLambdaName(JSFunction *fun) return (fun->flags & JSFUN_LAMBDA) ? fun->atom : NULL; } -static inline void -InitializeValueRange(HeapValue *vec, uintN len) -{ - for (uintN i = 0; i < len; i++) - vec[i].init(UndefinedValue()); -} - } /* namespace js */ inline const js::Value & @@ -980,14 +973,14 @@ JSObject::initializeSlotRange(size_t start, size_t length) size_t fixed = numFixedSlots(); if (start < fixed) { if (start + length < fixed) { - js::InitializeValueRange(fixedSlots() + start, length); + js::InitValueRange(fixedSlots() + start, length, false); } else { size_t localClear = fixed - start; - js::InitializeValueRange(fixedSlots() + start, localClear); - js::InitializeValueRange(slots, length - localClear); + js::InitValueRange(fixedSlots() + start, localClear, false); + js::InitValueRange(slots, length - localClear, false); } } else { - js::InitializeValueRange(slots + start - fixed, length); + js::InitValueRange(slots + start - fixed, length, false); } } @@ -1978,8 +1971,8 @@ JSObject::privateWriteBarrierPre(void **old) #ifdef JSGC_INCREMENTAL JSCompartment *comp = compartment(); if (comp->needsBarrier()) { - if (clasp->trace && *old) - clasp->trace(comp->barrierTracer(), this); + if (*old && getClass()->trace) + getClass()->trace(comp->barrierTracer(), this); } #endif } diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index de22e071e84..68d7c2c44c8 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -1259,8 +1259,15 @@ BaseShape::lookup(JSContext *cx, const BaseShape &base) return NULL; BaseShapeSet::AddPtr p = table.lookupForAdd(&base); - if (p) - return *p; + + if (p) { + UnownedBaseShape *base = *p; + + if (cx->compartment->needsBarrier()) + BaseShape::readBarrier(base); + + return base; + } BaseShape *nbase_ = js_NewGCBaseShape(cx); if (!nbase_) @@ -1355,8 +1362,15 @@ EmptyShape::lookupInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSO InitialShapeEntry::Lookup lookup(clasp, proto, parent, nfixed); InitialShapeSet::AddPtr p = table.lookupForAdd(lookup); - if (p) - return p->shape; + + if (p) { + Shape *shape = p->shape; + + if (cx->compartment->needsBarrier()) + Shape::readBarrier(shape); + + return shape; + } BaseShape base(clasp, parent, objectFlags); BaseShape *nbase = BaseShape::lookup(cx, base); diff --git a/js/src/jsscope.h b/js/src/jsscope.h index 3bfd541f662..80210138457 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -410,35 +410,16 @@ class BaseShape : public js::gc::Cell public: void finalize(JSContext *cx, bool background); - BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags) { - JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK)); - PodZero(this); - this->clasp = clasp; - this->parent = parent; - this->flags = objectFlags; - } - - BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags, - uint8 attrs, js::PropertyOp rawGetter, js::StrictPropertyOp rawSetter) { - JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK)); - PodZero(this); - this->clasp = clasp; - this->parent = parent; - this->flags = objectFlags; - this->rawGetter = rawGetter; - this->rawSetter = rawSetter; - if ((attrs & JSPROP_GETTER) && rawGetter) - flags |= HAS_GETTER_OBJECT; - if ((attrs & JSPROP_SETTER) && rawSetter) - flags |= HAS_SETTER_OBJECT; - } - - inline void adoptUnowned(UnownedBaseShape *other); + inline BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags); + inline BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags, + uint8 attrs, js::PropertyOp rawGetter, js::StrictPropertyOp rawSetter); bool isOwned() const { return !!(flags & OWNED_SHAPE); } - void setOwned(UnownedBaseShape *unowned) { flags |= OWNED_SHAPE; this->unowned_ = unowned; } - void setParent(JSObject *obj) { parent = obj; } + inline void adoptUnowned(UnownedBaseShape *other); + inline void setOwned(UnownedBaseShape *unowned); + + inline void setParent(JSObject *obj); JSObject *getObjectParent() { return parent; } void setObjectFlag(Flag flag) { JS_ASSERT(!(flag & ~OBJECT_FLAG_MASK)); flags |= flag; } @@ -473,8 +454,9 @@ class BaseShape : public js::gc::Cell static inline size_t offsetOfParent() { return offsetof(BaseShape, parent); } static inline size_t offsetOfFlags() { return offsetof(BaseShape, flags); } - inline static void writeBarrierPre(const BaseShape *shape); - inline static void writeBarrierPost(const BaseShape *shape, void *addr); + static inline void writeBarrierPre(BaseShape *shape); + static inline void writeBarrierPost(BaseShape *shape, void *addr); + static inline void readBarrier(BaseShape *shape); private: static void staticAsserts() { @@ -582,13 +564,7 @@ struct Shape : public js::gc::Cell bool hashify(JSContext *cx); void handoffTableTo(Shape *newShape); - void setParent(js::Shape *p) { - JS_ASSERT_IF(p && !p->hasMissingSlot() && !inDictionary(), - p->maybeSlot() <= maybeSlot()); - JS_ASSERT_IF(p && !inDictionary(), - hasSlot() == (p->maybeSlot() != maybeSlot())); - parent = p; - } + inline void setParent(js::Shape *p); bool ensureOwnBaseShape(JSContext *cx) { if (base()->isOwned()) @@ -946,15 +922,15 @@ struct Shape : public js::gc::Cell void finalize(JSContext *cx, bool background); void removeChild(js::Shape *child); - inline static void writeBarrierPre(const Shape *shape); - inline static void writeBarrierPost(const Shape *shape, void *addr); + static inline void writeBarrierPre(const Shape *shape); + static inline void writeBarrierPost(const Shape *shape, void *addr); /* * All weak references need a read barrier for incremental GC. This getter * method implements the read barrier. It's used to obtain initial shapes * from the compartment. */ - inline static void readBarrier(const js::Shape *shape); + static inline void readBarrier(const Shape *shape); /* For JIT usage */ static inline size_t offsetOfBase() { return offsetof(Shape, base_); } diff --git a/js/src/jsscopeinlines.h b/js/src/jsscopeinlines.h index 2b5415c5a8e..3f0f39bf507 100644 --- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -81,6 +81,39 @@ JSObject::extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom) namespace js { +inline +BaseShape::BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags) +{ + JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK)); + PodZero(this); + this->clasp = clasp; + this->parent = parent; + this->flags = objectFlags; +} + +inline +BaseShape::BaseShape(Class *clasp, JSObject *parent, uint32 objectFlags, + uint8 attrs, js::PropertyOp rawGetter, js::StrictPropertyOp rawSetter) +{ + JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK)); + PodZero(this); + this->clasp = clasp; + this->parent = parent; + this->flags = objectFlags; + this->rawGetter = rawGetter; + this->rawSetter = rawSetter; + if ((attrs & JSPROP_GETTER) && rawGetter) + flags |= HAS_GETTER_OBJECT; + if ((attrs & JSPROP_SETTER) && rawSetter) + flags |= HAS_SETTER_OBJECT; +} + +inline void +BaseShape::setParent(JSObject *obj) +{ + parent = obj; +} + inline void BaseShape::adoptUnowned(UnownedBaseShape *other) { @@ -104,6 +137,13 @@ BaseShape::adoptUnowned(UnownedBaseShape *other) setSlotSpan(span); } +inline void +BaseShape::setOwned(UnownedBaseShape *unowned) +{ + flags |= OWNED_SHAPE; + this->unowned_ = unowned; +} + inline Shape::Shape(BaseShape *base, jsid propid, uint32 slot, uint32 nfixed, uintN attrs, uintN flags, intN shortid) @@ -225,6 +265,16 @@ Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const return js::CallJSPropertyOpSetter(cx, setterOp(), obj, getUserId(), strict, vp); } +inline void +Shape::setParent(js::Shape *p) +{ + JS_ASSERT_IF(p && !p->hasMissingSlot() && !inDictionary(), + p->maybeSlot() <= maybeSlot()); + JS_ASSERT_IF(p && !inDictionary(), + hasSlot() == (p->maybeSlot() != maybeSlot())); + parent = p; +} + inline void Shape::removeFromDictionary(JSObject *obj) { @@ -303,17 +353,18 @@ Shape::writeBarrierPost(const js::Shape *shape, void *addr) } inline void -Shape::readBarrier(const js::Shape *base) +Shape::readBarrier(const Shape *shape) { #ifdef JSGC_INCREMENTAL - JSCompartment *comp = base->compartment(); - if (comp->needsBarrier()) - MarkBaseShapeUnbarriered(comp->barrierTracer(), base, "read barrier"); + JSCompartment *comp = shape->compartment(); + JS_ASSERT(comp->needsBarrier()); + + MarkShapeUnbarriered(comp->barrierTracer(), shape, "read barrier"); #endif } inline void -BaseShape::writeBarrierPre(const BaseShape *base) +BaseShape::writeBarrierPre(BaseShape *base) { #ifdef JSGC_INCREMENTAL if (!base) @@ -326,10 +377,21 @@ BaseShape::writeBarrierPre(const BaseShape *base) } inline void -BaseShape::writeBarrierPost(const BaseShape *shape, void *addr) +BaseShape::writeBarrierPost(BaseShape *shape, void *addr) { } +inline void +BaseShape::readBarrier(BaseShape *base) +{ +#ifdef JSGC_INCREMENTAL + JSCompartment *comp = base->compartment(); + JS_ASSERT(comp->needsBarrier()); + + MarkBaseShapeUnbarriered(comp->barrierTracer(), base, "read barrier"); +#endif +} + } /* namespace js */ #endif /* jsscopeinlines_h___ */ diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 2e66d8c603a..65882d83af0 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -176,9 +176,7 @@ class Bindings { uint16 nupvars; public: - inline Bindings(JSContext *cx) - : lastBinding(NULL), nargs(0), nvars(0), nupvars(0) - {} + inline Bindings(JSContext *cx); /* * Transfers ownership of bindings data from bindings into this fresh diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index 0cc33b2be1d..1e60c152e26 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -56,6 +56,11 @@ namespace js { +inline +Bindings::Bindings(JSContext *cx) + : lastBinding(NULL), nargs(0), nvars(0), nupvars(0) +{} + inline void Bindings::transfer(JSContext *cx, Bindings *bindings) {