mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 903519 - Disable nursery strings in a Zone if too many get tenured, r=sfink
--HG-- extra : rebase_source : 8ffe985d04ef182a7c4900172c6b8bd422ca4879 extra : intermediate-source : 2d3891634ce0a8e76af0e7227ff36ebbeae124d2 extra : source : bb2cc298a15583b524102372d42f722aae5d505a
This commit is contained in:
parent
27ebcf6d42
commit
53412618be
@ -182,7 +182,11 @@ js::AllocateString(JSContext* cx, InitialHeap heap)
|
||||
if (!rt->gc.checkAllocatorState<allowGC>(cx, kind))
|
||||
return nullptr;
|
||||
|
||||
if (cx->nursery().isEnabled() && heap != TenuredHeap && cx->nursery().canAllocateStrings()) {
|
||||
if (cx->nursery().isEnabled() &&
|
||||
heap != TenuredHeap &&
|
||||
cx->nursery().canAllocateStrings() &&
|
||||
cx->zone()->allocNurseryStrings)
|
||||
{
|
||||
auto str = static_cast<StringAllocT*>(rt->gc.tryNewNurseryString<allowGC>(cx, size, kind));
|
||||
if (str)
|
||||
return str;
|
||||
|
@ -738,21 +738,40 @@ js::Nursery::collect(JS::gcreason::Reason reason)
|
||||
bool validPromotionRate;
|
||||
const float promotionRate = calcPromotionRate(&validPromotionRate);
|
||||
uint32_t pretenureCount = 0;
|
||||
if (validPromotionRate) {
|
||||
if (promotionRate > 0.8 || IsFullStoreBufferReason(reason)) {
|
||||
JSContext* cx = TlsContext.get();
|
||||
for (auto& entry : tenureCounts.entries) {
|
||||
if (entry.count >= 3000) {
|
||||
ObjectGroup* group = entry.group;
|
||||
if (group->canPreTenure() && group->zone()->group()->canEnterWithoutYielding(cx)) {
|
||||
AutoCompartment ac(cx, group);
|
||||
group->setShouldPreTenure(cx);
|
||||
pretenureCount++;
|
||||
}
|
||||
bool shouldPretenure = (validPromotionRate && promotionRate > 0.6) ||
|
||||
IsFullStoreBufferReason(reason);
|
||||
|
||||
if (shouldPretenure) {
|
||||
JSContext* cx = TlsContext.get();
|
||||
for (auto& entry : tenureCounts.entries) {
|
||||
if (entry.count >= 3000) {
|
||||
ObjectGroup* group = entry.group;
|
||||
if (group->canPreTenure() && group->zone()->group()->canEnterWithoutYielding(cx)) {
|
||||
AutoCompartment ac(cx, group);
|
||||
group->setShouldPreTenure(cx);
|
||||
pretenureCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
|
||||
if (shouldPretenure && zone->allocNurseryStrings && zone->tenuredStrings >= 30 * 1000) {
|
||||
JSRuntime::AutoProhibitActiveContextChange apacc(rt);
|
||||
CancelOffThreadIonCompile(zone);
|
||||
bool preserving = zone->isPreservingCode();
|
||||
zone->setPreservingCode(false);
|
||||
zone->discardJitCode(rt->defaultFreeOp());
|
||||
zone->setPreservingCode(preserving);
|
||||
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
|
||||
if (jit::JitCompartment* jitComp = c->jitCompartment()) {
|
||||
jitComp->discardStubs();
|
||||
jitComp->stringsCanBeInNursery = false;
|
||||
}
|
||||
}
|
||||
zone->allocNurseryStrings = false;
|
||||
}
|
||||
zone->tenuredStrings = 0;
|
||||
}
|
||||
endProfile(ProfileKey::Pretenure);
|
||||
|
||||
// We ignore gcMaxBytes when allocating for minor collection. However, if we
|
||||
@ -1086,7 +1105,7 @@ js::Nursery::setStartPosition()
|
||||
void
|
||||
js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason)
|
||||
{
|
||||
static const double GrowThreshold = 0.05;
|
||||
static const double GrowThreshold = 0.03;
|
||||
static const double ShrinkThreshold = 0.01;
|
||||
unsigned newMaxNurseryChunks;
|
||||
|
||||
|
@ -46,6 +46,8 @@ JS::Zone::Zone(JSRuntime* rt, ZoneGroup* group)
|
||||
usage(&rt->gc.usage),
|
||||
threshold(),
|
||||
gcDelayBytes(0),
|
||||
tenuredStrings(group, 0),
|
||||
allocNurseryStrings(group, true),
|
||||
propertyTree_(group, this),
|
||||
baseShapes_(group, this),
|
||||
initialShapes_(group, this),
|
||||
|
@ -482,6 +482,9 @@ struct Zone : public JS::shadow::Zone,
|
||||
// the current GC.
|
||||
js::UnprotectedData<size_t> gcDelayBytes;
|
||||
|
||||
js::ZoneGroupData<uint32_t> tenuredStrings;
|
||||
js::ZoneGroupData<bool> allocNurseryStrings;
|
||||
|
||||
private:
|
||||
// Shared Shape property tree.
|
||||
js::ZoneGroupData<js::PropertyTree> propertyTree_;
|
||||
|
@ -205,7 +205,9 @@ CompileZone::addressOfStringNurseryCurrentEnd()
|
||||
bool
|
||||
CompileZone::canNurseryAllocateStrings()
|
||||
{
|
||||
return nurseryExists() && zone()->group()->nursery().canAllocateStrings();
|
||||
return nurseryExists() &&
|
||||
zone()->group()->nursery().canAllocateStrings() &&
|
||||
zone()->allocNurseryStrings;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -610,6 +610,13 @@ class JitCompartment
|
||||
return stringConcatStub_;
|
||||
}
|
||||
|
||||
void discardStubs() {
|
||||
stringConcatStub_ = nullptr;
|
||||
regExpMatcherStub_ = nullptr;
|
||||
regExpSearcherStub_ = nullptr;
|
||||
regExpTesterStub_ = nullptr;
|
||||
}
|
||||
|
||||
JitCode* regExpMatcherStubNoBarrier() const {
|
||||
return regExpMatcherStub_;
|
||||
}
|
||||
|
@ -219,6 +219,7 @@ GetSelectorRuntime(const CompilationSelector& selector)
|
||||
{
|
||||
JSRuntime* match(JSScript* script) { return script->runtimeFromActiveCooperatingThread(); }
|
||||
JSRuntime* match(JSCompartment* comp) { return comp->runtimeFromActiveCooperatingThread(); }
|
||||
JSRuntime* match(Zone* zone) { return zone->runtimeFromActiveCooperatingThread(); }
|
||||
JSRuntime* match(ZonesInState zbs) { return zbs.runtime; }
|
||||
JSRuntime* match(JSRuntime* runtime) { return runtime; }
|
||||
JSRuntime* match(AllCompilations all) { return nullptr; }
|
||||
@ -235,6 +236,7 @@ JitDataStructuresExist(const CompilationSelector& selector)
|
||||
{
|
||||
bool match(JSScript* script) { return !!script->compartment()->jitCompartment(); }
|
||||
bool match(JSCompartment* comp) { return !!comp->jitCompartment(); }
|
||||
bool match(Zone* zone) { return !!zone->jitZone(); }
|
||||
bool match(ZonesInState zbs) { return zbs.runtime->hasJitRuntime(); }
|
||||
bool match(JSRuntime* runtime) { return runtime->hasJitRuntime(); }
|
||||
bool match(AllCompilations all) { return true; }
|
||||
@ -253,6 +255,7 @@ IonBuilderMatches(const CompilationSelector& selector, jit::IonBuilder* builder)
|
||||
|
||||
bool match(JSScript* script) { return script == builder_->script(); }
|
||||
bool match(JSCompartment* comp) { return comp == builder_->script()->compartment(); }
|
||||
bool match(Zone* zone) { return zone == builder_->script()->zone(); }
|
||||
bool match(JSRuntime* runtime) { return runtime == builder_->script()->runtimeFromAnyThread(); }
|
||||
bool match(AllCompilations all) { return true; }
|
||||
bool match(ZonesInState zbs) {
|
||||
|
@ -519,6 +519,7 @@ struct CompilationsUsingNursery { JSRuntime* runtime; };
|
||||
|
||||
using CompilationSelector = mozilla::Variant<JSScript*,
|
||||
JSCompartment*,
|
||||
Zone*,
|
||||
ZonesInState,
|
||||
JSRuntime*,
|
||||
CompilationsUsingNursery,
|
||||
@ -542,6 +543,12 @@ CancelOffThreadIonCompile(JSCompartment* comp)
|
||||
CancelOffThreadIonCompile(CompilationSelector(comp), true);
|
||||
}
|
||||
|
||||
inline void
|
||||
CancelOffThreadIonCompile(Zone* zone)
|
||||
{
|
||||
CancelOffThreadIonCompile(CompilationSelector(zone), true);
|
||||
}
|
||||
|
||||
inline void
|
||||
CancelOffThreadIonCompile(JSRuntime* runtime, JS::Zone::GCState state)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user