зеркало из https://github.com/mozilla/gecko-dev.git
Bug 793823 - Exactly root Bindings when on the stack; r=billm
Currently, we rely on the marking of the origin script to keep the stack binding's data live. This will not work with a moving GC.
This commit is contained in:
Родитель
77154c4ab6
Коммит
c1fb5bcfc2
|
@ -959,44 +959,47 @@ InFreeList(ArenaHeader *aheader, uintptr_t addr)
|
|||
}
|
||||
|
||||
#ifdef JSGC_USE_EXACT_ROOTING
|
||||
static inline void
|
||||
MarkExactStackRooter(JSTracer *trc, Rooted<void*> rooter, ThingRootKind kind)
|
||||
{
|
||||
void **addr = (void **)rooter->address();
|
||||
if (!*addr)
|
||||
return;
|
||||
|
||||
switch (kind) {
|
||||
case THING_ROOT_OBJECT: MarkObjectRoot(trc, (JSObject **)addr, "exact-object"); break;
|
||||
case THING_ROOT_STRING: MarkStringRoot(trc, (JSSTring **)addr, "exact-string"); break;
|
||||
case THING_ROOT_SCRIPT: MarkScriptRoot(trc, (JSScript **)addr, "exact-script"); break;
|
||||
case THING_ROOT_SHAPE: MarkShapeRoot(trc, (Shape **)addr, "exact-shape"); break;
|
||||
case THING_ROOT_BASE_SHAPE: MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact-baseshape"); break;
|
||||
case THING_ROOT_TYPE: MarkTypeRoot(trc, (types::Type *)addr, "exact-type"); break;
|
||||
case THING_ROOT_TYPE_OBJECT: MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact-typeobject"); break;
|
||||
case THING_ROOT_VALUE: MarkValueRoot(trc, (Value *)addr, "exact-value"); break;
|
||||
case THING_ROOT_ID: MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
|
||||
case THING_ROOT_PROPERTY_ID: MarkIdRoot(trc, &((js::PropertyId *)addr)->asId(), "exact-propertyid"); break;
|
||||
case THING_ROOT_BINDINGS: ((Bindings *)addr)->trace(trc); break;
|
||||
default: JS_NOT_REACHED("Invalid THING_ROOT kind"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
MarkExactStackRooters(JSTracer *trc, Rooted<void*> rooter, ThingRootKind kind)
|
||||
{
|
||||
Rooted<void*> *rooter = cx->thingGCRooters[i];
|
||||
while (rooter) {
|
||||
MarkExactStackRoot(trc, rooter, ThingRootKind(i));
|
||||
rooter = rooter->previous();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
MarkExactStackRoots(JSTracer *trc)
|
||||
{
|
||||
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
||||
Rooted<void*> *rooter = cx->thingGCRooters[i];
|
||||
while (rooter) {
|
||||
void **addr = (void **)rooter->address();
|
||||
if (*addr) {
|
||||
if (i == THING_ROOT_OBJECT) {
|
||||
MarkObjectRoot(trc, (JSObject **)addr, "exact stackroot object");
|
||||
} else if (i == THING_ROOT_STRING) {
|
||||
MarkStringRoot(trc, (JSString **)addr, "exact stackroot string");
|
||||
} else if (i == THING_ROOT_ID) {
|
||||
MarkIdRoot(trc, (jsid *)addr, "exact stackroot id");
|
||||
} else if (i == THING_ROOT_PROPERTY_ID) {
|
||||
MarkIdRoot(trc, &((PropertyId *)addr)->asId(), "exact stackroot property id");
|
||||
} else if (i == THING_ROOT_VALUE) {
|
||||
MarkValueRoot(trc, (Value *)addr, "exact stackroot value");
|
||||
} else if (i == THING_ROOT_TYPE) {
|
||||
MarkTypeRoot(trc, (types::Type *)addr, "exact stackroot type");
|
||||
} else if (i == THING_ROOT_SHAPE) {
|
||||
MarkShapeRoot(trc, (Shape **)addr, "exact stackroot shape");
|
||||
} else if (i == THING_ROOT_BASE_SHAPE) {
|
||||
MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact stackroot baseshape");
|
||||
} else if (i == THING_ROOT_TYPE_OBJECT) {
|
||||
MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact stackroot typeobject");
|
||||
} else if (i == THING_ROOT_SCRIPT) {
|
||||
MarkScriptRoot(trc, (JSScript **)addr, "exact stackroot script");
|
||||
} else if (i == THING_ROOT_XML) {
|
||||
MarkXMLRoot(trc, (JSXML **)addr, "exact stackroot xml");
|
||||
} else {
|
||||
JS_NOT_REACHED("Invalid thing root kind.");
|
||||
}
|
||||
}
|
||||
rooter = rooter->previous();
|
||||
}
|
||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
||||
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
||||
MarkExactStackRooters(trc, cx->thingGCRooters[i], ThingRootKind(i));
|
||||
}
|
||||
MarkExactStackRooters(trc, rt->thingGCRooters[i], ThingRootKind(i));
|
||||
}
|
||||
}
|
||||
#endif /* JSGC_USE_EXACT_ROOTING */
|
||||
|
@ -4970,11 +4973,21 @@ SetValidateGC(JSContext *cx, bool enabled)
|
|||
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
CheckStackRootThing(uintptr_t *w, void *address, ThingRootKind kind)
|
||||
{
|
||||
if (kind != THING_ROOT_BINDINGS)
|
||||
return address == static_cast<void*>(w);
|
||||
|
||||
Bindings *bp = static_cast<Bindings*>(address);
|
||||
return w >= (uintptr_t*)bp && w < (uintptr_t*)(bp + 1);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE void
|
||||
CheckStackRootThings(uintptr_t *w, Rooted<void*> *rooter, bool *matched)
|
||||
CheckStackRootThings(uintptr_t *w, Rooted<void*> *rooter, ThingRootKind kind, bool *matched)
|
||||
{
|
||||
while (rooter) {
|
||||
if (rooter->address() == static_cast<void*>(w))
|
||||
if (CheckStackRootThing(w, rooter->address(), kind))
|
||||
*matched = true;
|
||||
rooter = rooter->previous();
|
||||
}
|
||||
|
@ -4994,9 +5007,9 @@ CheckStackRoot(JSTracer *trc, uintptr_t *w)
|
|||
bool matched = false;
|
||||
JSRuntime *rt = trc->runtime;
|
||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
||||
CheckStackRootThings(w, rt->thingGCRooters[i], &matched);
|
||||
CheckStackRootThings(w, rt->thingGCRooters[i], ThingRootKind(i), &matched);
|
||||
for (ContextIter cx(rt); !cx.done(); cx.next()) {
|
||||
CheckStackRootThings(w, cx->thingGCRooters[i], &matched);
|
||||
CheckStackRootThings(w, cx->thingGCRooters[i], ThingRootKind(i), &matched);
|
||||
SkipRoot *skip = cx->skipGCRooters;
|
||||
while (skip) {
|
||||
if (skip->contains(reinterpret_cast<uint8_t*>(w), sizeof(w)))
|
||||
|
|
|
@ -240,6 +240,7 @@ enum ThingRootKind
|
|||
THING_ROOT_PROPERTY_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_TYPE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
|
|
|
@ -93,9 +93,12 @@ Bindings::initWithTemporaryStorage(JSContext *cx, InternalHandle<Bindings*> self
|
|||
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == 2);
|
||||
gc::AllocKind allocKind = gc::FINALIZE_OBJECT2_BACKGROUND;
|
||||
JS_ASSERT(gc::GetGCKindSlots(allocKind) == CallObject::RESERVED_SLOTS);
|
||||
self->callObjShape_ =
|
||||
RootedShape initial(cx,
|
||||
EmptyShape::getInitialShape(cx, &CallClass, NULL, cx->global(),
|
||||
allocKind, BaseShape::VAROBJ | BaseShape::DELEGATE);
|
||||
allocKind, BaseShape::VAROBJ | BaseShape::DELEGATE));
|
||||
if (!initial)
|
||||
return false;
|
||||
self->callObjShape_.init(initial);
|
||||
|
||||
#ifdef DEBUG
|
||||
HashSet<PropertyName *> added(cx);
|
||||
|
@ -169,6 +172,12 @@ Bindings::clone(JSContext *cx, InternalHandle<Bindings*> self,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */ Bindings
|
||||
RootMethods<Bindings>::initial()
|
||||
{
|
||||
return Bindings();
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
static bool
|
||||
XDRScriptBindings(XDRState<mode> *xdr, LifoAllocScope &las, unsigned numArgs, unsigned numVars,
|
||||
|
@ -2090,9 +2099,9 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
|||
|
||||
/* Bindings */
|
||||
|
||||
Bindings bindings;
|
||||
Rooted<Bindings> bindings(cx);
|
||||
InternalHandle<Bindings*> bindingsHandle =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&bindings);
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(bindings.address());
|
||||
if (!Bindings::clone(cx, bindingsHandle, data, src))
|
||||
return NULL;
|
||||
|
||||
|
@ -2610,3 +2619,4 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
|
|||
{
|
||||
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,15 @@ class Bindings
|
|||
void trace(JSTracer *trc);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RootMethods<Bindings> {
|
||||
static Bindings initial();
|
||||
static ThingRootKind kind() { return THING_ROOT_BINDINGS; }
|
||||
static bool poisoned(const Bindings &bindings) {
|
||||
return IsPoisonedPtr(bindings.callObjShape());
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptCounts
|
||||
{
|
||||
friend struct ::JSScript;
|
||||
|
|
Загрузка…
Ссылка в новой задаче