mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
8a1b0e1843
commit
7b707cf94e
@ -959,44 +959,47 @@ InFreeList(ArenaHeader *aheader, uintptr_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JSGC_USE_EXACT_ROOTING
|
#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
|
static void
|
||||||
MarkExactStackRoots(JSTracer *trc)
|
MarkExactStackRoots(JSTracer *trc)
|
||||||
{
|
{
|
||||||
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
||||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
||||||
Rooted<void*> *rooter = cx->thingGCRooters[i];
|
MarkExactStackRooters(trc, cx->thingGCRooters[i], ThingRootKind(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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
MarkExactStackRooters(trc, rt->thingGCRooters[i], ThingRootKind(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* JSGC_USE_EXACT_ROOTING */
|
#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)
|
#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
|
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) {
|
while (rooter) {
|
||||||
if (rooter->address() == static_cast<void*>(w))
|
if (CheckStackRootThing(w, rooter->address(), kind))
|
||||||
*matched = true;
|
*matched = true;
|
||||||
rooter = rooter->previous();
|
rooter = rooter->previous();
|
||||||
}
|
}
|
||||||
@ -4994,9 +5007,9 @@ CheckStackRoot(JSTracer *trc, uintptr_t *w)
|
|||||||
bool matched = false;
|
bool matched = false;
|
||||||
JSRuntime *rt = trc->runtime;
|
JSRuntime *rt = trc->runtime;
|
||||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
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()) {
|
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;
|
SkipRoot *skip = cx->skipGCRooters;
|
||||||
while (skip) {
|
while (skip) {
|
||||||
if (skip->contains(reinterpret_cast<uint8_t*>(w), sizeof(w)))
|
if (skip->contains(reinterpret_cast<uint8_t*>(w), sizeof(w)))
|
||||||
|
@ -240,6 +240,7 @@ enum ThingRootKind
|
|||||||
THING_ROOT_PROPERTY_ID,
|
THING_ROOT_PROPERTY_ID,
|
||||||
THING_ROOT_VALUE,
|
THING_ROOT_VALUE,
|
||||||
THING_ROOT_TYPE,
|
THING_ROOT_TYPE,
|
||||||
|
THING_ROOT_BINDINGS,
|
||||||
THING_ROOT_LIMIT
|
THING_ROOT_LIMIT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,9 +93,12 @@ Bindings::initWithTemporaryStorage(JSContext *cx, InternalHandle<Bindings*> self
|
|||||||
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == 2);
|
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == 2);
|
||||||
gc::AllocKind allocKind = gc::FINALIZE_OBJECT2_BACKGROUND;
|
gc::AllocKind allocKind = gc::FINALIZE_OBJECT2_BACKGROUND;
|
||||||
JS_ASSERT(gc::GetGCKindSlots(allocKind) == CallObject::RESERVED_SLOTS);
|
JS_ASSERT(gc::GetGCKindSlots(allocKind) == CallObject::RESERVED_SLOTS);
|
||||||
self->callObjShape_ =
|
RootedShape initial(cx,
|
||||||
EmptyShape::getInitialShape(cx, &CallClass, NULL, cx->global(),
|
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
|
#ifdef DEBUG
|
||||||
HashSet<PropertyName *> added(cx);
|
HashSet<PropertyName *> added(cx);
|
||||||
@ -169,6 +172,12 @@ Bindings::clone(JSContext *cx, InternalHandle<Bindings*> self,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ Bindings
|
||||||
|
RootMethods<Bindings>::initial()
|
||||||
|
{
|
||||||
|
return Bindings();
|
||||||
|
}
|
||||||
|
|
||||||
template<XDRMode mode>
|
template<XDRMode mode>
|
||||||
static bool
|
static bool
|
||||||
XDRScriptBindings(XDRState<mode> *xdr, LifoAllocScope &las, unsigned numArgs, unsigned numVars,
|
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 bindings;
|
Rooted<Bindings> bindings(cx);
|
||||||
InternalHandle<Bindings*> bindingsHandle =
|
InternalHandle<Bindings*> bindingsHandle =
|
||||||
InternalHandle<Bindings*>::fromMarkedLocation(&bindings);
|
InternalHandle<Bindings*>::fromMarkedLocation(bindings.address());
|
||||||
if (!Bindings::clone(cx, bindingsHandle, data, src))
|
if (!Bindings::clone(cx, bindingsHandle, data, src))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -2610,3 +2619,4 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
|
|||||||
{
|
{
|
||||||
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
|
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +199,15 @@ class Bindings
|
|||||||
void trace(JSTracer *trc);
|
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
|
class ScriptCounts
|
||||||
{
|
{
|
||||||
friend struct ::JSScript;
|
friend struct ::JSScript;
|
||||||
|
Loading…
Reference in New Issue
Block a user