Bug 1149352 - Part 4: Move Symbol marking to TraceEdge; r=jonco

This commit is contained in:
Terrence Cole 2015-03-30 15:14:23 -07:00
parent 4f52ea7894
commit 33e799086c
6 changed files with 31 additions and 38 deletions

View File

@ -231,16 +231,10 @@ template <> struct MapTypeToTraceKind<UnownedBaseShape> { static const JSGCTrace
template <> struct MapTypeToTraceKind<jit::JitCode> { static const JSGCTraceKind kind = JSTRACE_JITCODE; };
template <> struct MapTypeToTraceKind<ObjectGroup> { static const JSGCTraceKind kind = JSTRACE_OBJECT_GROUP; };
// Direct value access used by the write barriers and the jits.
void
MarkValueForBarrier(JSTracer* trc, Value* v, const char* name);
// These three declarations are also present in gc/Marking.h, via the DeclMarker
// macro. Not great, but hard to avoid.
void
MarkStringUnbarriered(JSTracer* trc, JSString** str, const char* name);
void
MarkSymbolUnbarriered(JSTracer* trc, JS::Symbol** sym, const char* name);
// Marking.h depends on these barrier definitions, so we need a separate
// entry point for marking to implement the pre-barrier.
void MarkValueForBarrier(JSTracer* trc, Value* v, const char* name);
void MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name);
} // namespace gc
@ -283,6 +277,13 @@ ZoneOfValueFromAnyThread(const JS::Value& value)
return js::gc::TenuredCell::fromPointer(value.toGCThing())->zoneFromAnyThread();
}
MOZ_ALWAYS_INLINE JS::Zone*
ZoneOfIdFromAnyThread(const jsid& id)
{
MOZ_ASSERT(JSID_IS_GCTHING(id));
return js::gc::TenuredCell::fromPointer(JSID_TO_GCTHING(id).asCell())->zoneFromAnyThread();
}
void
ValueReadBarrier(const Value& value);
@ -387,19 +388,13 @@ struct InternalGCMethods<jsid>
static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); }
static void preBarrier(jsid id) {
if (JSID_IS_STRING(id)) {
JSString* str = JSID_TO_STRING(id);
JS::shadow::Zone* shadowZone = ShadowZoneOfStringFromAnyThread(str);
if (JSID_IS_GCTHING(id)) {
JS::Zone* zone = ZoneOfIdFromAnyThread(id);
JS::shadow::Zone* shadowZone = JS::shadow::Zone::asShadowZone(zone);
if (shadowZone->needsIncrementalBarrier()) {
js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &str, "write barrier");
MOZ_ASSERT(str == JSID_TO_STRING(id));
}
} else if (JSID_IS_SYMBOL(id)) {
JS::Symbol* sym = JSID_TO_SYMBOL(id);
JS::shadow::Zone* shadowZone = ShadowZoneOfSymbolFromAnyThread(sym);
if (shadowZone->needsIncrementalBarrier()) {
js::gc::MarkSymbolUnbarriered(shadowZone->barrierTracer(), &sym, "write barrier");
MOZ_ASSERT(sym == JSID_TO_SYMBOL(id));
jsid tmp(id);
js::gc::MarkIdForBarrier(shadowZone->barrierTracer(), &tmp, "id write barrier");
MOZ_ASSERT(tmp == id);
}
}
}

View File

@ -1117,7 +1117,6 @@ DeclMarkerImpl(String, JSString)
DeclMarkerImpl(String, JSFlatString)
DeclMarkerImpl(String, JSLinearString)
DeclMarkerImpl(String, PropertyName)
DeclMarkerImpl(Symbol, JS::Symbol)
DeclMarkerImpl(ObjectGroup, js::ObjectGroup)
} /* namespace gc */
@ -1310,10 +1309,16 @@ ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Value val)
/*** Special Marking ***/
void
gc::MarkValueForBarrier(JSTracer* trc, Value* v, const char* name)
gc::MarkValueForBarrier(JSTracer* trc, Value* valuep, const char* name)
{
MOZ_ASSERT(!trc->runtime()->isHeapBusy());
TraceManuallyBarrieredEdge(trc, v, name);
TraceManuallyBarrieredEdge(trc, valuep, name);
}
void
gc::MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name)
{
TraceManuallyBarrieredEdge(trc, idp, name);
}
/*** Push Mark Stack ***/

View File

@ -165,7 +165,6 @@ DeclMarker(String, JSString)
DeclMarker(String, JSFlatString)
DeclMarker(String, JSLinearString)
DeclMarker(String, PropertyName)
DeclMarker(Symbol, JS::Symbol)
DeclMarker(ObjectGroup, ObjectGroup)
#undef DeclMarker

View File

@ -100,7 +100,7 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer* trc)
MarkExactStackRootList<ObjectGroup*, MarkObjectGroupRoot>(
trc, context, "exact-objectgroup");
MarkExactStackRootList<JSString*, MarkStringRoot>(trc, context, "exact-string");
MarkExactStackRootList<JS::Symbol*, MarkSymbolRoot>(trc, context, "exact-symbol");
MarkExactStackRootList<JS::Symbol*, TraceRoot>(trc, context, "exact-symbol");
MarkExactStackRootList<jit::JitCode*, MarkJitCodeRoot>(trc, context, "exact-jitcode");
MarkExactStackRootList<JSScript*, TraceRoot>(trc, context, "exact-script");
MarkExactStackRootList<LazyScript*, TraceRoot>(trc, context, "exact-lazy-script");

View File

@ -1436,16 +1436,8 @@ ObjectGroupCompartment::sweep(FreeOp* fop)
if (IsAboutToBeFinalized(&entry.shape))
remove = true;
for (unsigned i = 0; !remove && i < key.nproperties; i++) {
if (JSID_IS_STRING(key.properties[i])) {
JSString* str = JSID_TO_STRING(key.properties[i]);
if (IsStringAboutToBeFinalized(&str))
remove = true;
MOZ_ASSERT(AtomToId((JSAtom*)str) == key.properties[i]);
} else if (JSID_IS_SYMBOL(key.properties[i])) {
JS::Symbol* sym = JSID_TO_SYMBOL(key.properties[i]);
if (IsSymbolAboutToBeFinalized(&sym))
remove = true;
}
if (gc::IsAboutToBeFinalizedUnbarriered(&key.properties[i]))
remove = true;
MOZ_ASSERT(!entry.types[i].isSingleton());
ObjectGroup* group = nullptr;

View File

@ -110,8 +110,10 @@ SymbolRegistry::sweep()
{
for (Enum e(*this); !e.empty(); e.popFront()) {
Symbol* sym = e.front();
if (IsSymbolAboutToBeFinalized(&sym))
if (IsAboutToBeFinalizedUnbarriered(&sym))
e.removeFront();
else
MOZ_ASSERT(sym == e.front());
}
}