Backed out 4 changesets (bug 1831072) for causing process crashes on Android 7 CLOSED TREE

Backed out changeset 424a49289df8 (bug 1831072)
Backed out changeset cc81053765a7 (bug 1831072)
Backed out changeset 7bec43b87e1d (bug 1831072)
Backed out changeset 8e0f85038c59 (bug 1831072)
This commit is contained in:
Norisz Fay 2023-05-04 15:04:04 +03:00
parent 6a99f49fca
commit 2004dce9a4
13 changed files with 91 additions and 46 deletions

View file

@ -7163,7 +7163,7 @@ static bool ClearMarkQueue(JSContext* cx, unsigned argc, Value* vp) {
static bool NurseryStringsEnabled(JSContext* cx, unsigned argc, Value* vp) { static bool NurseryStringsEnabled(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(cx->zone()->allocNurseryStrings()); args.rval().setBoolean(cx->zone()->allocNurseryStrings);
return true; return true;
} }

View file

@ -33,10 +33,10 @@ using namespace js;
using namespace gc; using namespace gc;
void Zone::updateNurseryAllocFlags(const Nursery& nursery) { void Zone::updateNurseryAllocFlags(const Nursery& nursery) {
allocNurseryObjects_ = nursery.isEnabled(); allocNurseryObjects = nursery.isEnabled();
allocNurseryStrings_ = nursery.isEnabled() && nursery.canAllocateStrings() && allocNurseryStrings = nursery.isEnabled() && nursery.canAllocateStrings() &&
!nurseryStringsDisabled; !nurseryStringsDisabled;
allocNurseryBigInts_ = nursery.isEnabled() && nursery.canAllocateBigInts() && allocNurseryBigInts = nursery.isEnabled() && nursery.canAllocateBigInts() &&
!nurseryBigIntsDisabled; !nurseryBigIntsDisabled;
} }
@ -63,7 +63,7 @@ void* gc::CellAllocator::AllocateObjectCell(JSContext* cx, AllocKind kind,
return nullptr; return nullptr;
} }
if (heap != TenuredHeap && cx->zone()->allocNurseryObjects()) { if (heap != TenuredHeap && cx->zone()->allocNurseryObjects) {
if (!site) { if (!site) {
site = cx->zone()->unknownAllocSite(JS::TraceKind::Object); site = cx->zone()->unknownAllocSite(JS::TraceKind::Object);
} }
@ -140,7 +140,7 @@ void* GCRuntime::tryNewNurseryStringCell(JSContext* cx, size_t thingSize,
// Exceeding gcMaxBytes while tenuring can disable the Nursery, and // Exceeding gcMaxBytes while tenuring can disable the Nursery, and
// other heuristics can disable nursery strings for this zone. // other heuristics can disable nursery strings for this zone.
if (cx->nursery().isEnabled() && cx->zone()->allocNurseryStrings()) { if (cx->nursery().isEnabled() && cx->zone()->allocNurseryStrings) {
return cx->nursery().allocateString(site, thingSize); return cx->nursery().allocateString(site, thingSize);
} }
} }
@ -162,7 +162,7 @@ void* gc::CellAllocator::AllocateStringCell(JSContext* cx, AllocKind kind,
return nullptr; return nullptr;
} }
if (heap != TenuredHeap && cx->zone()->allocNurseryStrings()) { if (heap != TenuredHeap && cx->zone()->allocNurseryStrings) {
void* ptr = rt->gc.tryNewNurseryStringCell<allowGC>(cx, size, kind); void* ptr = rt->gc.tryNewNurseryStringCell<allowGC>(cx, size, kind);
if (ptr) { if (ptr) {
return ptr; return ptr;
@ -208,7 +208,7 @@ void* GCRuntime::tryNewNurseryBigIntCell(JSContext* cx, size_t thingSize,
// Exceeding gcMaxBytes while tenuring can disable the Nursery, and // Exceeding gcMaxBytes while tenuring can disable the Nursery, and
// other heuristics can disable nursery BigInts for this zone. // other heuristics can disable nursery BigInts for this zone.
if (cx->nursery().isEnabled() && cx->zone()->allocNurseryBigInts()) { if (cx->nursery().isEnabled() && cx->zone()->allocNurseryBigInts) {
return cx->nursery().allocateBigInt(site, thingSize); return cx->nursery().allocateBigInt(site, thingSize);
} }
} }
@ -229,7 +229,7 @@ void* gc::CellAllocator::AllocateBigIntCell(JSContext* cx, InitialHeap heap) {
return nullptr; return nullptr;
} }
if (heap != TenuredHeap && cx->zone()->allocNurseryBigInts()) { if (heap != TenuredHeap && cx->zone()->allocNurseryBigInts) {
void* ptr = rt->gc.tryNewNurseryBigIntCell<allowGC>(cx, size, kind); void* ptr = rt->gc.tryNewNurseryBigIntCell<allowGC>(cx, size, kind);
if (ptr) { if (ptr) {
return ptr; return ptr;

View file

@ -3291,7 +3291,10 @@ void GCRuntime::maybeStopPretenuring() {
double rate = double(zone->finalizedStrings) / double(numStrings); double rate = double(zone->finalizedStrings) / double(numStrings);
if (rate > tunables.stopPretenureStringThreshold()) { if (rate > tunables.stopPretenureStringThreshold()) {
CancelOffThreadIonCompile(zone); CancelOffThreadIonCompile(zone);
zone->forceDiscardJitCode(rt->gcContext()); bool preserving = zone->isPreservingCode();
zone->setPreservingCode(false);
zone->discardJitCode(rt->gcContext());
zone->setPreservingCode(preserving);
for (RealmsInZoneIter r(zone); !r.done(); r.next()) { for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
if (jit::JitRealm* jitRealm = r->jitRealm()) { if (jit::JitRealm* jitRealm = r->jitRealm()) {
jitRealm->discardStubs(); jitRealm->discardStubs();

View file

@ -95,7 +95,8 @@ void js::ReleaseAllJITCode(JS::GCContext* gcx) {
js::CancelOffThreadIonCompile(gcx->runtime()); js::CancelOffThreadIonCompile(gcx->runtime());
for (ZonesIter zone(gcx->runtime(), SkipAtoms); !zone.done(); zone.next()) { for (ZonesIter zone(gcx->runtime(), SkipAtoms); !zone.done(); zone.next()) {
zone->forceDiscardJitCode(gcx); zone->setPreservingCode(false);
zone->discardJitCode(gcx);
} }
for (RealmsIter realm(gcx->runtime()); !realm.done(); realm.next()) { for (RealmsIter realm(gcx->runtime()); !realm.done(); realm.next()) {

View file

@ -862,6 +862,17 @@ void js::Nursery::renderProfileJSON(JSONPrinter& json) const {
stats().allocsSinceMinorGCTenured()); stats().allocsSinceMinorGCTenured());
} }
if (stats().getStat(gcstats::STAT_NURSERY_STRING_REALMS_DISABLED)) {
json.property(
"nursery_string_realms_disabled",
stats().getStat(gcstats::STAT_NURSERY_STRING_REALMS_DISABLED));
}
if (stats().getStat(gcstats::STAT_NURSERY_BIGINT_REALMS_DISABLED)) {
json.property(
"nursery_bigint_realms_disabled",
stats().getStat(gcstats::STAT_NURSERY_BIGINT_REALMS_DISABLED));
}
json.beginObjectProperty("phase_times"); json.beginObjectProperty("phase_times");
#define EXTRACT_NAME(name, text) #name, #define EXTRACT_NAME(name, text) #name,
@ -1542,8 +1553,11 @@ size_t js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason,
reason, JS::GCReason::FULL_CELL_PTR_BIGINT_BUFFER); reason, JS::GCReason::FULL_CELL_PTR_BIGINT_BUFFER);
} }
mozilla::Maybe<AutoGCSession> session;
uint32_t numStringsTenured = 0; uint32_t numStringsTenured = 0;
uint32_t numNurseryStringRealmsDisabled = 0;
uint32_t numBigIntsTenured = 0; uint32_t numBigIntsTenured = 0;
uint32_t numNurseryBigIntRealmsDisabled = 0;
for (ZonesIter zone(gc, SkipAtoms); !zone.done(); zone.next()) { for (ZonesIter zone(gc, SkipAtoms); !zone.done(); zone.next()) {
// For some tests in JetStream2 and Kraken, the tenuredRate is high but the // For some tests in JetStream2 and Kraken, the tenuredRate is high but the
// number of allocated strings is low. So we calculate the tenuredRate only // number of allocated strings is low. So we calculate the tenuredRate only
@ -1558,19 +1572,28 @@ size_t js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason,
allocThreshold ? double(zoneTenuredStrings) / double(zoneNurseryStrings) allocThreshold ? double(zoneTenuredStrings) / double(zoneNurseryStrings)
: 0.0; : 0.0;
bool disableNurseryStrings = bool disableNurseryStrings =
pretenureStr && zone->allocNurseryStrings() && pretenureStr && zone->allocNurseryStrings &&
tenuredRate > tunables().pretenureStringThreshold(); tenuredRate > tunables().pretenureStringThreshold();
bool disableNurseryBigInts = pretenureBigInt && bool disableNurseryBigInts = pretenureBigInt && zone->allocNurseryBigInts &&
zone->allocNurseryBigInts() &&
zone->tenuredBigInts >= 30 * 1000; zone->tenuredBigInts >= 30 * 1000;
if (disableNurseryStrings || disableNurseryBigInts) { if (disableNurseryStrings || disableNurseryBigInts) {
if (!session.isSome()) {
session.emplace(gc, JS::HeapState::MinorCollecting);
}
CancelOffThreadIonCompile(zone); CancelOffThreadIonCompile(zone);
zone->forceDiscardJitCode(rt->gcContext()); bool preserving = zone->isPreservingCode();
zone->setPreservingCode(false);
zone->discardJitCode(rt->gcContext());
zone->setPreservingCode(preserving);
for (RealmsInZoneIter r(zone); !r.done(); r.next()) { for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
if (jit::JitRealm* jitRealm = r->jitRealm()) { if (jit::JitRealm* jitRealm = r->jitRealm()) {
jitRealm->discardStubs(); jitRealm->discardStubs();
if (disableNurseryStrings) { if (disableNurseryStrings) {
jitRealm->setStringsCanBeInNursery(false); jitRealm->setStringsCanBeInNursery(false);
numNurseryStringRealmsDisabled++;
}
if (disableNurseryBigInts) {
numNurseryBigIntRealmsDisabled++;
} }
} }
} }
@ -1586,7 +1609,12 @@ size_t js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason,
numBigIntsTenured += zone->tenuredBigInts; numBigIntsTenured += zone->tenuredBigInts;
zone->tenuredBigInts = 0; zone->tenuredBigInts = 0;
} }
session.reset(); // End the minor GC session, if running one.
stats().setStat(gcstats::STAT_NURSERY_STRING_REALMS_DISABLED,
numNurseryStringRealmsDisabled);
stats().setStat(gcstats::STAT_STRINGS_TENURED, numStringsTenured); stats().setStat(gcstats::STAT_STRINGS_TENURED, numStringsTenured);
stats().setStat(gcstats::STAT_NURSERY_BIGINT_REALMS_DISABLED,
numNurseryBigIntRealmsDisabled);
stats().setStat(gcstats::STAT_BIGINTS_TENURED, numBigIntsTenured); stats().setStat(gcstats::STAT_BIGINTS_TENURED, numBigIntsTenured);
return sitesPretenured; return sitesPretenured;

View file

@ -70,6 +70,9 @@ JS_PUBLIC_API void JS::SetSiteBasedPretenuringEnabled(bool enable) {
SiteBasedPretenuringEnabled = enable; SiteBasedPretenuringEnabled = enable;
} }
class PretenuringNursery::MaybeGCSession
: public mozilla::Maybe<AutoGCSession> {};
bool PretenuringNursery::canCreateAllocSite() { bool PretenuringNursery::canCreateAllocSite() {
MOZ_ASSERT(allocSitesCreated <= MaxAllocSitesPerMinorGC); MOZ_ASSERT(allocSitesCreated <= MaxAllocSitesPerMinorGC);
return SiteBasedPretenuringEnabled && return SiteBasedPretenuringEnabled &&
@ -80,6 +83,8 @@ size_t PretenuringNursery::doPretenuring(GCRuntime* gc, JS::GCReason reason,
bool validPromotionRate, bool validPromotionRate,
double promotionRate, bool reportInfo, double promotionRate, bool reportInfo,
size_t reportThreshold) { size_t reportThreshold) {
MaybeGCSession session;
size_t sitesActive = 0; size_t sitesActive = 0;
size_t sitesPretenured = 0; size_t sitesPretenured = 0;
size_t sitesInvalidated = 0; size_t sitesInvalidated = 0;
@ -123,7 +128,7 @@ size_t PretenuringNursery::doPretenuring(GCRuntime* gc, JS::GCReason reason,
if (site->isNormal()) { if (site->isNormal()) {
processSite(gc, site, sitesActive, sitesPretenured, sitesInvalidated, processSite(gc, site, sitesActive, sitesPretenured, sitesInvalidated,
reportInfo, reportThreshold); session, reportInfo, reportThreshold);
} }
site = next; site = next;
@ -156,7 +161,8 @@ size_t PretenuringNursery::doPretenuring(GCRuntime* gc, JS::GCReason reason,
void PretenuringNursery::processSite(GCRuntime* gc, AllocSite* site, void PretenuringNursery::processSite(GCRuntime* gc, AllocSite* site,
size_t& sitesActive, size_t& sitesActive,
size_t& sitesPretenured, size_t& sitesPretenured,
size_t& sitesInvalidated, bool reportInfo, size_t& sitesInvalidated,
MaybeGCSession& session, bool reportInfo,
size_t reportThreshold) { size_t reportThreshold) {
sitesActive++; sitesActive++;
@ -180,6 +186,11 @@ void PretenuringNursery::processSite(GCRuntime* gc, AllocSite* site,
// We can optimize JIT code before we realise that a site should be // We can optimize JIT code before we realise that a site should be
// pretenured. Make sure we invalidate any existing optimized code. // pretenured. Make sure we invalidate any existing optimized code.
if (!session.isSome()) {
session.emplace(gc, JS::HeapState::MinorCollecting);
}
if (site->hasScript()) { if (site->hasScript()) {
wasInvalidated = site->invalidateScript(gc); wasInvalidated = site->invalidateScript(gc);
if (wasInvalidated) { if (wasInvalidated) {

View file

@ -334,9 +334,11 @@ class PretenuringNursery {
void* addressOfAllocatedSites() { return &allocatedSites; } void* addressOfAllocatedSites() { return &allocatedSites; }
private: private:
class MaybeGCSession;
void processSite(GCRuntime* gc, AllocSite* site, size_t& sitesActive, void processSite(GCRuntime* gc, AllocSite* site, size_t& sitesActive,
size_t& sitesPretenured, size_t& sitesInvalidated, size_t& sitesPretenured, size_t& sitesInvalidated,
bool reportInfo, size_t reportThreshold); MaybeGCSession& session, bool reportInfo,
size_t reportThreshold);
void processCatchAllSite(AllocSite* site, bool reportInfo, void processCatchAllSite(AllocSite* site, bool reportInfo,
size_t reportThreshold); size_t reportThreshold);
void updateAllocCounts(AllocSite* site); void updateAllocCounts(AllocSite* site);

View file

@ -67,9 +67,17 @@ enum Stat {
// Number of strings deduplicated. // Number of strings deduplicated.
STAT_STRINGS_DEDUPLICATED, STAT_STRINGS_DEDUPLICATED,
// Number of realms that had nursery strings disabled due to large numbers
// being tenured.
STAT_NURSERY_STRING_REALMS_DISABLED,
// Number of BigInts tenured. // Number of BigInts tenured.
STAT_BIGINTS_TENURED, STAT_BIGINTS_TENURED,
// Number of realms that had nursery BigInts disabled due to large numbers
// being tenured.
STAT_NURSERY_BIGINT_REALMS_DISABLED,
STAT_LIMIT STAT_LIMIT
}; };

View file

@ -161,9 +161,8 @@ JS::Zone::Zone(JSRuntime* rt, Kind kind)
tenuredBigInts(0), tenuredBigInts(0),
markedStrings(0), markedStrings(0),
finalizedStrings(0), finalizedStrings(0),
allocNurseryObjects_(true), allocNurseryStrings(true),
allocNurseryStrings_(true), allocNurseryBigInts(true),
allocNurseryBigInts_(true),
suppressAllocationMetadataBuilder(false), suppressAllocationMetadataBuilder(false),
pretenuring(this), pretenuring(this),
compartments_(), compartments_(),
@ -386,17 +385,14 @@ void Zone::checkStringWrappersAfterMovingGC() {
#endif #endif
void Zone::discardJitCode(JS::GCContext* gcx, const DiscardOptions& options) { void Zone::discardJitCode(JS::GCContext* gcx, const DiscardOptions& options) {
if (!isPreservingCode()) {
forceDiscardJitCode(gcx, options);
}
}
void Zone::forceDiscardJitCode(JS::GCContext* gcx,
const DiscardOptions& options) {
if (!jitZone()) { if (!jitZone()) {
return; return;
} }
if (isPreservingCode()) {
return;
}
if (options.discardJitScripts && options.discardBaselineCode) { if (options.discardJitScripts && options.discardBaselineCode) {
lastDiscardedCodeTime_ = mozilla::TimeStamp::Now(); lastDiscardedCodeTime_ = mozilla::TimeStamp::Now();
} }

View file

@ -181,14 +181,12 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
js::MainThreadData<bool> nurseryStringsDisabled; js::MainThreadData<bool> nurseryStringsDisabled;
js::MainThreadData<bool> nurseryBigIntsDisabled; js::MainThreadData<bool> nurseryBigIntsDisabled;
private:
// Flags dynamically updated based on more than one condition, including the // Flags dynamically updated based on more than one condition, including the
// flags above. // flags above.
js::MainThreadData<bool> allocNurseryObjects_; js::MainThreadData<bool> allocNurseryObjects;
js::MainThreadData<bool> allocNurseryStrings_; js::MainThreadData<bool> allocNurseryStrings;
js::MainThreadData<bool> allocNurseryBigInts_; js::MainThreadData<bool> allocNurseryBigInts;
public:
// When true, skip calling the metadata callback. We use this: // When true, skip calling the metadata callback. We use this:
// - to avoid invoking the callback recursively; // - to avoid invoking the callback recursively;
// - to avoid observing lazy prototype setup (which confuses callbacks that // - to avoid observing lazy prototype setup (which confuses callbacks that
@ -329,10 +327,6 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
void discardJitCode(JS::GCContext* gcx, void discardJitCode(JS::GCContext* gcx,
const DiscardOptions& options = DiscardOptions()); const DiscardOptions& options = DiscardOptions());
// Discard JIT code regardless of isPreservingCode().
void forceDiscardJitCode(JS::GCContext* gcx,
const DiscardOptions& options = DiscardOptions());
void resetAllocSitesAndInvalidate(bool resetNurserySites, void resetAllocSitesAndInvalidate(bool resetNurserySites,
bool resetPretenuredSites); bool resetPretenuredSites);
@ -471,9 +465,6 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
void fixupScriptMapsAfterMovingGC(JSTracer* trc); void fixupScriptMapsAfterMovingGC(JSTracer* trc);
void updateNurseryAllocFlags(const js::Nursery& nursery); void updateNurseryAllocFlags(const js::Nursery& nursery);
bool allocNurseryObjects() const { return allocNurseryObjects_; }
bool allocNurseryStrings() const { return allocNurseryStrings_; }
bool allocNurseryBigInts() const { return allocNurseryBigInts_; }
mozilla::LinkedList<detail::WeakCacheBase>& weakCaches() { mozilla::LinkedList<detail::WeakCacheBase>& weakCaches() {
return weakCaches_.ref(); return weakCaches_.ref();

View file

@ -5764,7 +5764,10 @@ bool CacheIRCompiler::emitStoreTypedArrayElement(ObjOperandId objId,
static gc::InitialHeap InitialBigIntHeap(JSContext* cx) { static gc::InitialHeap InitialBigIntHeap(JSContext* cx) {
JS::Zone* zone = cx->zone(); JS::Zone* zone = cx->zone();
return zone->allocNurseryBigInts() ? gc::DefaultHeap : gc::TenuredHeap; bool canNurseryAllocate =
zone->runtimeFromAnyThread()->gc.nursery().canAllocateBigInts() &&
zone->allocNurseryBigInts;
return canNurseryAllocate ? gc::DefaultHeap : gc::TenuredHeap;
} }
static void EmitAllocateBigInt(MacroAssembler& masm, Register result, static void EmitAllocateBigInt(MacroAssembler& masm, Register result,

View file

@ -172,11 +172,13 @@ void* CompileZone::addressOfNurseryAllocatedSites() {
} }
bool CompileZone::canNurseryAllocateStrings() { bool CompileZone::canNurseryAllocateStrings() {
return zone()->allocNurseryStrings(); return zone()->runtimeFromAnyThread()->gc.nursery().canAllocateStrings() &&
zone()->allocNurseryStrings;
} }
bool CompileZone::canNurseryAllocateBigInts() { bool CompileZone::canNurseryAllocateBigInts() {
return zone()->allocNurseryBigInts(); return zone()->runtimeFromAnyThread()->gc.nursery().canAllocateBigInts() &&
zone()->allocNurseryBigInts;
} }
gc::AllocSite* CompileZone::catchAllAllocSite(JS::TraceKind traceKind, gc::AllocSite* CompileZone::catchAllAllocSite(JS::TraceKind traceKind,

View file

@ -135,7 +135,7 @@ bool Realm::ensureJitRealmExists(JSContext* cx) {
return false; return false;
} }
jitRealm->initialize(zone()->allocNurseryStrings()); jitRealm->initialize(zone()->allocNurseryStrings);
jitRealm_ = std::move(jitRealm); jitRealm_ = std::move(jitRealm);
return true; return true;