Bug 1507379 - Make some nursery string values available in the profiler r=sfink
authorPaul Bone <pbone@mozilla.com>
Fri, 16 Nov 2018 16:53:05 +1100
changeset 507408 47750e022e23d5b4eb445443a737a04ba9b45391
parent 507407 b12b2142017abdb8cce3ea9758ed0af16c398e15
child 507409 85ed5eb2a3663f024355370b1a6b7df35582a79d
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1507379
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1507379 - Make some nursery string values available in the profiler r=sfink
js/src/gc/Nursery.cpp
js/src/gc/Statistics.h
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -630,16 +630,17 @@ js::Nursery::renderProfileJSON(JSONPrint
 
     json.beginObject();
 
     json.property("status", "complete");
 
     json.property("reason", JS::gcreason::ExplainReason(previousGC.reason));
     json.property("bytes_tenured", previousGC.tenuredBytes);
     json.property("cells_tenured", previousGC.tenuredCells);
+    json.property("strings_tenured", stats().getStat(gcstats::STAT_STRINGS_TENURED));
     json.property("bytes_used", previousGC.nurseryUsedBytes);
     json.property("cur_capacity", previousGC.nurseryCapacity);
     const size_t newCapacity = spaceToEnd(maxChunkCount());
     if (newCapacity != previousGC.nurseryCapacity) {
         json.property("new_capacity", newCapacity);
     }
     if (previousGC.nurseryLazyCapacity != previousGC.nurseryCapacity) {
         json.property("lazy_capacity", previousGC.nurseryLazyCapacity);
@@ -656,16 +657,20 @@ js::Nursery::renderProfileJSON(JSONPrint
         json.property("cells_allocated_tenured",
             stats().allocsSinceMinorGCTenured());
     }
 
     if (stats().getStat(gcstats::STAT_OBJECT_GROUPS_PRETENURED)) {
         json.property("groups_pretenured",
             stats().getStat(gcstats::STAT_OBJECT_GROUPS_PRETENURED));
     }
+    if (stats().getStat(gcstats::STAT_NURSERY_STRING_REALMS_DISABLED)) {
+        json.property("nursery_string_realms_disabled",
+            stats().getStat(gcstats::STAT_NURSERY_STRING_REALMS_DISABLED));
+    }
 
     json.beginObjectProperty("phase_times");
 
 #define EXTRACT_NAME(name, text) #name,
     static const char* const names[] = {
 FOR_EACH_NURSERY_PROFILE_TIME(EXTRACT_NAME)
 #undef EXTRACT_NAME
     "" };
@@ -828,37 +833,43 @@ js::Nursery::collect(JS::gcreason::Reaso
                     pretenureCount++;
                 }
             }
         }
     }
     stats().setStat(gcstats::STAT_OBJECT_GROUPS_PRETENURED, pretenureCount);
 
     mozilla::Maybe<AutoGCSession> session;
+    uint32_t numStringsTenured = 0;
+    uint32_t numNurseryStringRealmsDisabled = 0;
     for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
         if (shouldPretenure && zone->allocNurseryStrings && zone->tenuredStrings >= 30 * 1000) {
             if (!session.isSome()) {
                 session.emplace(rt, JS::HeapState::MinorCollecting);
             }
             CancelOffThreadIonCompile(zone);
             bool preserving = zone->isPreservingCode();
             zone->setPreservingCode(false);
             zone->discardJitCode(rt->defaultFreeOp());
             zone->setPreservingCode(preserving);
             for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
                 if (jit::JitRealm* jitRealm = r->jitRealm()) {
                     jitRealm->discardStubs();
                     jitRealm->stringsCanBeInNursery = false;
+                    numNurseryStringRealmsDisabled++;
                 }
             }
             zone->allocNurseryStrings = false;
         }
+        numStringsTenured += zone->tenuredStrings;
         zone->tenuredStrings = 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);
     endProfile(ProfileKey::Pretenure);
 
     // We ignore gcMaxBytes when allocating for minor collection. However, if we
     // overflowed, we disable the nursery. The next time we allocate, we'll fail
     // because gcBytes >= gcMaxBytes.
     if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes()) {
         disable();
     }
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -45,19 +45,25 @@ enum Count {
     // Number of arenas relocated by compacting GC.
     COUNT_ARENA_RELOCATED,
 
     COUNT_LIMIT
 };
 
 // Stats can be set with Statistics::setStat(). They're not reset automatically.
 enum Stat {
+    // Number of strings tenured.
+    STAT_STRINGS_TENURED,
+
     // Number of object types pretenured this minor GC.
     STAT_OBJECT_GROUPS_PRETENURED,
 
+    // Number of realms that had nursery strings disabled due to large numbers being tenured.
+    STAT_NURSERY_STRING_REALMS_DISABLED,
+
     STAT_LIMIT
 };
 
 struct ZoneGCStats
 {
     /* Number of zones collected in this GC. */
     int collectedZoneCount = 0;