Loading js/src/gc/Barrier-inl.h +4 −2 Original line number Diff line number Diff line Loading @@ -294,8 +294,10 @@ HeapId::pre() if (JS_UNLIKELY(JSID_IS_OBJECT(value))) { JSObject *obj = JSID_TO_OBJECT(value); JSCompartment *comp = obj->compartment(); if (comp->needsBarrier()) js::gc::MarkObjectUnbarriered(comp->barrierTracer(), obj, "write barrier"); if (comp->needsBarrier()) { js::gc::MarkObjectUnbarriered(comp->barrierTracer(), &obj, "write barrier"); JS_ASSERT(obj == JSID_TO_OBJECT(value)); } } #endif } Loading js/src/jsapi.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -4264,7 +4264,9 @@ prop_iter_trace(JSTracer *trc, JSObject *obj) * barrier here because the pointer is updated via setPrivate, which * always takes a barrier. */ MarkShapeUnbarriered(trc, (Shape *)pdata, "prop iter shape"); Shape *tmp = (Shape *)pdata; MarkShapeUnbarriered(trc, &tmp, "prop iter shape"); obj->setPrivate(tmp); } else { /* Non-native case: mark each id in the JSIdArray private. */ JSIdArray *ida = (JSIdArray *) pdata; Loading js/src/jsarray.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1193,7 +1193,7 @@ array_trace(JSTracer *trc, JSObject *obj) JS_ASSERT(obj->isDenseArray()); uint32_t initLength = obj->getDenseArrayInitializedLength(); MarkSlotRange(trc, initLength, obj->getDenseArrayElements(), "element"); MarkArraySlots(trc, initLength, obj->getDenseArrayElements(), "element"); } static JSBool Loading js/src/jsfun.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -1094,13 +1094,13 @@ JSFunction::trace(JSTracer *trc) } if (atom) MarkStringUnbarriered(trc, atom, "atom"); MarkStringUnbarriered(trc, &atom, "atom"); if (isInterpreted()) { if (script()) MarkScript(trc, &script(), "script"); if (environment()) MarkObjectUnbarriered(trc, environment(), "fun_callscope"); if (u.i.script_) MarkScriptUnbarriered(trc, &u.i.script_, "script"); if (u.i.env_) MarkObjectUnbarriered(trc, &u.i.env_, "fun_callscope"); } } Loading js/src/jsgcmark.cpp +40 −101 Original line number Diff line number Diff line Loading @@ -126,10 +126,10 @@ MarkInternal(JSTracer *trc, T *thing) template <typename T> static void MarkUnbarriered(JSTracer *trc, T *thing, const char *name) MarkUnbarriered(JSTracer *trc, T **thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thing); MarkInternal(trc, *thingp); } template <typename T> Loading Loading @@ -186,9 +186,9 @@ Mark##base##Root(JSTracer *trc, type **thingp, const char *name) } \ \ void \ Mark##base##Unbarriered(JSTracer *trc, type *thing, const char *name) \ Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name) \ { \ MarkUnbarriered<type>(trc, thing, name); \ MarkUnbarriered<type>(trc, thingp, name); \ } \ \ void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *vec, const char *name) \ Loading @@ -202,6 +202,7 @@ void Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *na } \ DeclMarkerImpl(BaseShape, BaseShape) DeclMarkerImpl(BaseShape, UnownedBaseShape) DeclMarkerImpl(Object, ArgumentsObject) DeclMarkerImpl(Object, GlobalObject) DeclMarkerImpl(Object, JSObject) Loading Loading @@ -366,7 +367,7 @@ MarkSlot(JSTracer *trc, HeapSlot *s, const char *name) } void MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); Loading @@ -374,6 +375,16 @@ MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) } } void MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots) { JS_ASSERT(obj->isNative()); for (uint32_t i = start; i < (start + nslots); ++i) { JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet()); } } void MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) { Loading @@ -393,15 +404,11 @@ MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) /*** Special Marking ***/ /* * The unioned HeapPtr stored in script->globalObj needs special treatment to * typecheck correctly. */ static void MarkObject(JSTracer *trc, const HeapPtr<GlobalObject, JSScript *> &thing, const char *name) void MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thing.get()); MarkInternal(trc, thingp->get()); } void Loading Loading @@ -644,113 +651,34 @@ PushMarkStack(GCMarker *gcmarker, JSString *str) void MarkChildren(JSTracer *trc, JSObject *obj) { MarkTypeObject(trc, &obj->typeFromGC(), "type"); Shape *shape = obj->lastProperty(); MarkShapeUnbarriered(trc, shape, "shape"); Class *clasp = shape->getObjectClass(); if (clasp->trace) clasp->trace(trc, obj); if (shape->isNative()) { uint32_t nslots = obj->slotSpan(); for (uint32_t i = 0; i < nslots; i++) { JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet()); } } obj->markChildren(trc); } static void MarkChildren(JSTracer *trc, JSString *str) { /* * We use custom barriers in JSString, so it's safe to use unbarriered * marking here. */ if (str->isDependent()) { MarkStringUnbarriered(trc, str->asDependent().base(), "base"); } else if (str->isRope()) { JSRope &rope = str->asRope(); MarkStringUnbarriered(trc, rope.leftChild(), "left child"); MarkStringUnbarriered(trc, rope.rightChild(), "right child"); } if (str->isDependent()) str->asDependent().markChildren(trc); else if (str->isRope()) str->asRope().markChildren(trc); } static void MarkChildren(JSTracer *trc, JSScript *script) { CheckScript(script, NULL); JS_ASSERT_IF(trc->runtime->gcCheckCompartment, script->compartment() == trc->runtime->gcCheckCompartment); for (uint32_t i = 0; i < script->natoms; ++i) { if (JSAtom *p = script->atoms[i]) MarkStringUnbarriered(trc, p, "atom"); } if (JSScript::isValidOffset(script->objectsOffset)) { JSObjectArray *objarray = script->objects(); MarkObjectRange(trc, objarray->length, objarray->vector, "objects"); } if (JSScript::isValidOffset(script->regexpsOffset)) { JSObjectArray *objarray = script->regexps(); MarkObjectRange(trc, objarray->length, objarray->vector, "objects"); } if (JSScript::isValidOffset(script->constOffset)) { JSConstArray *constarray = script->consts(); MarkValueRange(trc, constarray->length, constarray->vector, "consts"); } if (script->function()) MarkObjectUnbarriered(trc, script->function(), "function"); if (!script->isCachedEval && script->globalObject) MarkObject(trc, script->globalObject, "object"); if (IS_GC_MARKING_TRACER(trc) && script->filename) js_MarkScriptFilename(script->filename); script->bindings.trace(trc); if (script->types) script->types->trace(trc); if (script->hasAnyBreakpointsOrStepMode()) script->markTrapClosures(trc); script->markChildren(trc); } static void MarkChildren(JSTracer *trc, Shape *shape) { MarkBaseShapeUnbarriered(trc, shape->base(), "base"); MarkId(trc, &shape->propidRef(), "propid"); if (shape->previous()) MarkShape(trc, &shape->previousRef(), "parent"); } static inline void MarkBaseShapeGetterSetter(JSTracer *trc, BaseShape *base) { if (base->hasGetterObject()) MarkObjectUnbarriered(trc, base->getterObject(), "getter"); if (base->hasSetterObject()) MarkObjectUnbarriered(trc, base->setterObject(), "setter"); shape->markChildren(trc); } static void MarkChildren(JSTracer *trc, BaseShape *base) { MarkBaseShapeGetterSetter(trc, base); if (base->isOwned()) MarkBaseShapeUnbarriered(trc, base->baseUnowned(), "base"); if (JSObject *parent = base->getObjectParent()) MarkObjectUnbarriered(trc, parent, "parent"); base->markChildren(trc); } /* Loading @@ -773,11 +701,22 @@ MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent */ base->assertConsistency(); MarkBaseShapeGetterSetter(trc, base); if (base->hasGetterObject()) { JSObject *tmp = base->getterObject(); MarkObjectUnbarriered(trc, &tmp, "getter"); JS_ASSERT(tmp == base->getterObject()); } if (base->hasSetterObject()) { JSObject *tmp = base->setterObject(); MarkObjectUnbarriered(trc, &tmp, "setter"); JS_ASSERT(tmp == base->setterObject()); } JSObject *parent = base->getObjectParent(); if (parent && parent != *prevParent) { MarkObjectUnbarriered(trc, parent, "parent"); MarkObjectUnbarriered(trc, &parent, "parent"); JS_ASSERT(parent == base->getObjectParent()); *prevParent = parent; } } Loading Loading
js/src/gc/Barrier-inl.h +4 −2 Original line number Diff line number Diff line Loading @@ -294,8 +294,10 @@ HeapId::pre() if (JS_UNLIKELY(JSID_IS_OBJECT(value))) { JSObject *obj = JSID_TO_OBJECT(value); JSCompartment *comp = obj->compartment(); if (comp->needsBarrier()) js::gc::MarkObjectUnbarriered(comp->barrierTracer(), obj, "write barrier"); if (comp->needsBarrier()) { js::gc::MarkObjectUnbarriered(comp->barrierTracer(), &obj, "write barrier"); JS_ASSERT(obj == JSID_TO_OBJECT(value)); } } #endif } Loading
js/src/jsapi.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -4264,7 +4264,9 @@ prop_iter_trace(JSTracer *trc, JSObject *obj) * barrier here because the pointer is updated via setPrivate, which * always takes a barrier. */ MarkShapeUnbarriered(trc, (Shape *)pdata, "prop iter shape"); Shape *tmp = (Shape *)pdata; MarkShapeUnbarriered(trc, &tmp, "prop iter shape"); obj->setPrivate(tmp); } else { /* Non-native case: mark each id in the JSIdArray private. */ JSIdArray *ida = (JSIdArray *) pdata; Loading
js/src/jsarray.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1193,7 +1193,7 @@ array_trace(JSTracer *trc, JSObject *obj) JS_ASSERT(obj->isDenseArray()); uint32_t initLength = obj->getDenseArrayInitializedLength(); MarkSlotRange(trc, initLength, obj->getDenseArrayElements(), "element"); MarkArraySlots(trc, initLength, obj->getDenseArrayElements(), "element"); } static JSBool Loading
js/src/jsfun.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -1094,13 +1094,13 @@ JSFunction::trace(JSTracer *trc) } if (atom) MarkStringUnbarriered(trc, atom, "atom"); MarkStringUnbarriered(trc, &atom, "atom"); if (isInterpreted()) { if (script()) MarkScript(trc, &script(), "script"); if (environment()) MarkObjectUnbarriered(trc, environment(), "fun_callscope"); if (u.i.script_) MarkScriptUnbarriered(trc, &u.i.script_, "script"); if (u.i.env_) MarkObjectUnbarriered(trc, &u.i.env_, "fun_callscope"); } } Loading
js/src/jsgcmark.cpp +40 −101 Original line number Diff line number Diff line Loading @@ -126,10 +126,10 @@ MarkInternal(JSTracer *trc, T *thing) template <typename T> static void MarkUnbarriered(JSTracer *trc, T *thing, const char *name) MarkUnbarriered(JSTracer *trc, T **thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thing); MarkInternal(trc, *thingp); } template <typename T> Loading Loading @@ -186,9 +186,9 @@ Mark##base##Root(JSTracer *trc, type **thingp, const char *name) } \ \ void \ Mark##base##Unbarriered(JSTracer *trc, type *thing, const char *name) \ Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name) \ { \ MarkUnbarriered<type>(trc, thing, name); \ MarkUnbarriered<type>(trc, thingp, name); \ } \ \ void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *vec, const char *name) \ Loading @@ -202,6 +202,7 @@ void Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *na } \ DeclMarkerImpl(BaseShape, BaseShape) DeclMarkerImpl(BaseShape, UnownedBaseShape) DeclMarkerImpl(Object, ArgumentsObject) DeclMarkerImpl(Object, GlobalObject) DeclMarkerImpl(Object, JSObject) Loading Loading @@ -366,7 +367,7 @@ MarkSlot(JSTracer *trc, HeapSlot *s, const char *name) } void MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); Loading @@ -374,6 +375,16 @@ MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) } } void MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots) { JS_ASSERT(obj->isNative()); for (uint32_t i = start; i < (start + nslots); ++i) { JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet()); } } void MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) { Loading @@ -393,15 +404,11 @@ MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) /*** Special Marking ***/ /* * The unioned HeapPtr stored in script->globalObj needs special treatment to * typecheck correctly. */ static void MarkObject(JSTracer *trc, const HeapPtr<GlobalObject, JSScript *> &thing, const char *name) void MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thing.get()); MarkInternal(trc, thingp->get()); } void Loading Loading @@ -644,113 +651,34 @@ PushMarkStack(GCMarker *gcmarker, JSString *str) void MarkChildren(JSTracer *trc, JSObject *obj) { MarkTypeObject(trc, &obj->typeFromGC(), "type"); Shape *shape = obj->lastProperty(); MarkShapeUnbarriered(trc, shape, "shape"); Class *clasp = shape->getObjectClass(); if (clasp->trace) clasp->trace(trc, obj); if (shape->isNative()) { uint32_t nslots = obj->slotSpan(); for (uint32_t i = 0; i < nslots; i++) { JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet()); } } obj->markChildren(trc); } static void MarkChildren(JSTracer *trc, JSString *str) { /* * We use custom barriers in JSString, so it's safe to use unbarriered * marking here. */ if (str->isDependent()) { MarkStringUnbarriered(trc, str->asDependent().base(), "base"); } else if (str->isRope()) { JSRope &rope = str->asRope(); MarkStringUnbarriered(trc, rope.leftChild(), "left child"); MarkStringUnbarriered(trc, rope.rightChild(), "right child"); } if (str->isDependent()) str->asDependent().markChildren(trc); else if (str->isRope()) str->asRope().markChildren(trc); } static void MarkChildren(JSTracer *trc, JSScript *script) { CheckScript(script, NULL); JS_ASSERT_IF(trc->runtime->gcCheckCompartment, script->compartment() == trc->runtime->gcCheckCompartment); for (uint32_t i = 0; i < script->natoms; ++i) { if (JSAtom *p = script->atoms[i]) MarkStringUnbarriered(trc, p, "atom"); } if (JSScript::isValidOffset(script->objectsOffset)) { JSObjectArray *objarray = script->objects(); MarkObjectRange(trc, objarray->length, objarray->vector, "objects"); } if (JSScript::isValidOffset(script->regexpsOffset)) { JSObjectArray *objarray = script->regexps(); MarkObjectRange(trc, objarray->length, objarray->vector, "objects"); } if (JSScript::isValidOffset(script->constOffset)) { JSConstArray *constarray = script->consts(); MarkValueRange(trc, constarray->length, constarray->vector, "consts"); } if (script->function()) MarkObjectUnbarriered(trc, script->function(), "function"); if (!script->isCachedEval && script->globalObject) MarkObject(trc, script->globalObject, "object"); if (IS_GC_MARKING_TRACER(trc) && script->filename) js_MarkScriptFilename(script->filename); script->bindings.trace(trc); if (script->types) script->types->trace(trc); if (script->hasAnyBreakpointsOrStepMode()) script->markTrapClosures(trc); script->markChildren(trc); } static void MarkChildren(JSTracer *trc, Shape *shape) { MarkBaseShapeUnbarriered(trc, shape->base(), "base"); MarkId(trc, &shape->propidRef(), "propid"); if (shape->previous()) MarkShape(trc, &shape->previousRef(), "parent"); } static inline void MarkBaseShapeGetterSetter(JSTracer *trc, BaseShape *base) { if (base->hasGetterObject()) MarkObjectUnbarriered(trc, base->getterObject(), "getter"); if (base->hasSetterObject()) MarkObjectUnbarriered(trc, base->setterObject(), "setter"); shape->markChildren(trc); } static void MarkChildren(JSTracer *trc, BaseShape *base) { MarkBaseShapeGetterSetter(trc, base); if (base->isOwned()) MarkBaseShapeUnbarriered(trc, base->baseUnowned(), "base"); if (JSObject *parent = base->getObjectParent()) MarkObjectUnbarriered(trc, parent, "parent"); base->markChildren(trc); } /* Loading @@ -773,11 +701,22 @@ MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent */ base->assertConsistency(); MarkBaseShapeGetterSetter(trc, base); if (base->hasGetterObject()) { JSObject *tmp = base->getterObject(); MarkObjectUnbarriered(trc, &tmp, "getter"); JS_ASSERT(tmp == base->getterObject()); } if (base->hasSetterObject()) { JSObject *tmp = base->setterObject(); MarkObjectUnbarriered(trc, &tmp, "setter"); JS_ASSERT(tmp == base->setterObject()); } JSObject *parent = base->getObjectParent(); if (parent && parent != *prevParent) { MarkObjectUnbarriered(trc, parent, "parent"); MarkObjectUnbarriered(trc, &parent, "parent"); JS_ASSERT(parent == base->getObjectParent()); *prevParent = parent; } } Loading