Bug 1338614 - Refactor incremental barrier APIs and make them call the read barrier r=sfink

This commit is contained in:
Jon Coppeard 2017-02-13 11:11:09 +00:00
Родитель df5929de3b
Коммит 46c6dced28
5 изменённых файлов: 40 добавлений и 42 удалений

Просмотреть файл

@ -425,25 +425,27 @@ extern JS_PUBLIC_API(bool)
IsIncrementalGCInProgress(JSContext* cx);
/*
* Returns true when writes to GC things must call an incremental (pre) barrier.
* This is generally only true when running mutator code in-between GC slices.
* At other times, the barrier may be elided for performance.
* Returns true when writes to GC thing pointers (and reads from weak pointers)
* must call an incremental barrier. This is generally only true when running
* mutator code in-between GC slices. At other times, the barrier may be elided
* for performance.
*/
extern JS_PUBLIC_API(bool)
IsIncrementalBarrierNeeded(JSContext* cx);
/*
* Notify the GC that a reference to a GC thing is about to be overwritten.
* These methods must be called if IsIncrementalBarrierNeeded.
* Notify the GC that a reference to a JSObject is about to be overwritten.
* This method must be called if IsIncrementalBarrierNeeded.
*/
extern JS_PUBLIC_API(void)
IncrementalReferenceBarrier(GCCellPtr thing);
IncrementalPreWriteBarrier(JSObject* obj);
/*
* Notify the GC that a weak reference to a GC thing has been read.
* This method must be called if IsIncrementalBarrierNeeded.
*/
extern JS_PUBLIC_API(void)
IncrementalValueBarrier(const Value& v);
extern JS_PUBLIC_API(void)
IncrementalObjectBarrier(JSObject* obj);
IncrementalReadBarrier(GCCellPtr thing);
/**
* Returns true if the most recent GC ran incrementally.
@ -643,13 +645,15 @@ ExposeGCThingToActiveJS(JS::GCCellPtr thing)
MOZ_DIAGNOSTIC_ASSERT(BarriersAreAllowedOnCurrentThread());
if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
JS::IncrementalReferenceBarrier(thing);
else if (!thing.mayBeOwnedByOtherRuntime() && js::gc::detail::CellIsMarkedGray(thing.asCell()))
JS::IncrementalReadBarrier(thing);
else if (js::gc::detail::CellIsMarkedGray(thing.asCell()))
JS::UnmarkGrayGCThingRecursively(thing);
MOZ_ASSERT(!js::gc::detail::CellIsMarkedGray(thing.asCell()));
}
static MOZ_ALWAYS_INLINE void
MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing)
GCThingReadBarrier(JS::GCCellPtr thing)
{
// Any object in the nursery will not be freed during any GC running at that
// time.
@ -664,7 +668,7 @@ MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing)
MOZ_DIAGNOSTIC_ASSERT(BarriersAreAllowedOnCurrentThread());
if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
JS::IncrementalReferenceBarrier(thing);
JS::IncrementalReadBarrier(thing);
}
} /* namespace gc */
@ -695,10 +699,10 @@ ExposeScriptToActiveJS(JSScript* script)
* If a GC is currently marking, mark the string black.
*/
static MOZ_ALWAYS_INLINE void
MarkStringAsLive(Zone* zone, JSString* string)
StringReadBarrier(JSString* string)
{
JSRuntime* rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromActiveCooperatingThread();
js::gc::MarkGCThingAsLive(rt, GCCellPtr(string));
MOZ_ASSERT(js::CurrentThreadCanAccessZone(GetStringZone(string)));
js::gc::GCThingReadBarrier(GCCellPtr(string));
}
/*

Просмотреть файл

@ -1207,13 +1207,13 @@ class JS_PUBLIC_API(ObjectPtr)
JSObject* unbarrieredGet() const { return value.unbarrieredGet(); }
void writeBarrierPre(JSContext* cx) {
IncrementalObjectBarrier(value);
IncrementalPreWriteBarrier(value);
}
void updateWeakPointerAfterGC();
ObjectPtr& operator=(JSObject* obj) {
IncrementalObjectBarrier(value);
IncrementalPreWriteBarrier(value);
value = obj;
return *this;
}

Просмотреть файл

@ -1225,7 +1225,7 @@ void
JS::ObjectPtr::finalize(JSRuntime* rt)
{
if (IsIncrementalBarrierNeeded(rt->activeContextFromOwnThread()))
IncrementalObjectBarrier(value);
IncrementalPreWriteBarrier(value);
value = nullptr;
}

Просмотреть файл

@ -7490,36 +7490,30 @@ JS::IsIncrementalBarrierNeeded(JSContext* cx)
return cx->runtime()->gc.state() == gc::State::Mark && !JS::CurrentThreadIsHeapBusy();
}
struct IncrementalReferenceBarrierFunctor {
template <typename T> void operator()(T* t) { T::writeBarrierPre(t); }
};
JS_PUBLIC_API(void)
JS::IncrementalReferenceBarrier(GCCellPtr thing)
{
if (!thing)
return;
DispatchTyped(IncrementalReferenceBarrierFunctor(), thing);
}
JS_PUBLIC_API(void)
JS::IncrementalValueBarrier(const Value& v)
{
js::GCPtrValue::writeBarrierPre(v);
}
JS_PUBLIC_API(void)
JS::IncrementalObjectBarrier(JSObject* obj)
JS::IncrementalPreWriteBarrier(JSObject* obj)
{
if (!obj)
return;
MOZ_ASSERT(!JS::CurrentThreadIsHeapMajorCollecting());
JSObject::writeBarrierPre(obj);
}
struct IncrementalReadBarrierFunctor {
template <typename T> void operator()(T* t) { T::readBarrier(t); }
};
JS_PUBLIC_API(void)
JS::IncrementalReadBarrier(GCCellPtr thing)
{
if (!thing)
return;
MOZ_ASSERT(!JS::CurrentThreadIsHeapMajorCollecting());
DispatchTyped(IncrementalReadBarrierFunctor(), thing);
}
JS_PUBLIC_API(bool)
JS::WasIncrementalGC(JSContext* cx)
{

Просмотреть файл

@ -261,7 +261,7 @@ public:
ZoneStringCache* cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
if (cache && buf == cache->mBuffer && length == cache->mLength) {
MOZ_ASSERT(JS::GetStringZone(cache->mString) == zone);
JS::MarkStringAsLive(zone, cache->mString);
JS::StringReadBarrier(cache->mString);
rval.setString(cache->mString);
*sharedBuffer = false;
return true;