зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1473213 (Part 4) - Add cells allocated statistics r=sfink
--HG-- extra : rebase_source : 667c5db83b674e28602fe38ca73bc6f250717c64
This commit is contained in:
Родитель
3e4c1ee795
Коммит
0c73982d50
|
@ -264,6 +264,7 @@ GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize)
|
|||
|
||||
checkIncrementalZoneState(cx, t);
|
||||
gcTracer.traceTenuredAlloc(t, kind);
|
||||
cx->noteTenuredAlloc();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -7935,6 +7935,14 @@ GCRuntime::minorGC(JS::gcreason::Reason reason, gcstats::PhaseKind phase)
|
|||
if (rt->mainContextFromOwnThread()->suppressGC)
|
||||
return;
|
||||
|
||||
// Note that we aren't collecting the updated alloc counts from any helper
|
||||
// threads. We should be but I'm not sure where to add that
|
||||
// synchronisation.
|
||||
uint32_t numAllocs = rt->mainContextFromOwnThread()->getAndResetAllocsThisZoneSinceMinorGC();
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
|
||||
numAllocs += zone->getAndResetTenuredAllocsSinceMinorGC();
|
||||
rt->gc.stats().setAllocsSinceMinorGCTenured(numAllocs);
|
||||
|
||||
gcstats::AutoPhase ap(rt->gc.stats(), phase);
|
||||
|
||||
nursery().clearMinorGCRequest();
|
||||
|
@ -8220,6 +8228,8 @@ GCRuntime::mergeRealms(Realm* source, Realm* target)
|
|||
|
||||
// Merge the allocator, stats and UIDs in source's zone into target's zone.
|
||||
target->zone()->arenas.adoptArenas(&source->zone()->arenas, targetZoneIsCollecting);
|
||||
target->zone()->addTenuredAllocsSinceMinorGC(
|
||||
source->zone()->getAndResetTenuredAllocsSinceMinorGC());
|
||||
target->zone()->usage.adopt(source->zone()->usage);
|
||||
target->zone()->adoptUniqueIds(source->zone());
|
||||
target->zone()->adoptMallocBytes(source->zone());
|
||||
|
|
|
@ -1023,6 +1023,9 @@ class GCRuntime
|
|||
const void* addressOfStringNurseryCurrentEnd() {
|
||||
return nursery_.refNoCheck().addressOfCurrentStringEnd();
|
||||
}
|
||||
uint32_t* addressOfNurseryAllocCount() {
|
||||
return stats().addressOfAllocsSinceMinorGCNursery();
|
||||
}
|
||||
|
||||
void minorGC(JS::gcreason::Reason reason,
|
||||
gcstats::PhaseKind phase = gcstats::PhaseKind::MINOR_GC) JS_HAZ_GC_CALL;
|
||||
|
|
|
@ -396,6 +396,7 @@ js::Nursery::allocate(size_t size)
|
|||
|
||||
void* thing = (void*)position();
|
||||
position_ = position() + size;
|
||||
runtime()->gc.stats().noteNurseryAlloc();
|
||||
|
||||
JS_EXTRA_POISON(thing, JS_ALLOCATED_NURSERY_PATTERN, size, MemCheckKind::MakeUndefined);
|
||||
|
||||
|
@ -620,6 +621,8 @@ js::Nursery::renderProfileJSON(JSONPrinter& json) const
|
|||
json.property("lazy_capacity", previousGC.nurseryLazyCapacity);
|
||||
if (!timeInChunkAlloc_.IsZero())
|
||||
json.property("chunk_alloc_us", timeInChunkAlloc_, json.MICROSECONDS);
|
||||
json.property("cells_allocated_nursery", runtime()->gc.stats().allocsSinceMinorGCNursery());
|
||||
json.property("cells_allocated_tenured", runtime()->gc.stats().allocsSinceMinorGCTenured());
|
||||
|
||||
json.beginObjectProperty("phase_times");
|
||||
|
||||
|
|
|
@ -752,6 +752,7 @@ Statistics::Statistics(JSRuntime* rt)
|
|||
gcTimerFile(nullptr),
|
||||
gcDebugFile(nullptr),
|
||||
nonincrementalReason_(gc::AbortReason::None),
|
||||
allocsSinceMinorGC({0, 0}),
|
||||
preBytes(0),
|
||||
thresholdTriggered(false),
|
||||
triggerAmount(0.0),
|
||||
|
@ -1046,6 +1047,8 @@ Statistics::endNurseryCollection(JS::gcreason::Reason reason)
|
|||
JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END,
|
||||
reason);
|
||||
}
|
||||
|
||||
allocsSinceMinorGC = {0, 0};
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -192,6 +192,27 @@ struct Statistics
|
|||
thresholdTriggered = true;
|
||||
}
|
||||
|
||||
void noteNurseryAlloc() {
|
||||
allocsSinceMinorGC.nursery++;
|
||||
}
|
||||
|
||||
// tenured allocs don't include nursery evictions.
|
||||
void setAllocsSinceMinorGCTenured(uint32_t allocs) {
|
||||
allocsSinceMinorGC.tenured = allocs;
|
||||
}
|
||||
|
||||
uint32_t allocsSinceMinorGCNursery() {
|
||||
return allocsSinceMinorGC.nursery;
|
||||
}
|
||||
|
||||
uint32_t allocsSinceMinorGCTenured() {
|
||||
return allocsSinceMinorGC.tenured;
|
||||
}
|
||||
|
||||
uint32_t* addressOfAllocsSinceMinorGCNursery() {
|
||||
return &allocsSinceMinorGC.nursery;
|
||||
}
|
||||
|
||||
void beginNurseryCollection(JS::gcreason::Reason reason);
|
||||
void endNurseryCollection(JS::gcreason::Reason reason);
|
||||
|
||||
|
@ -315,6 +336,15 @@ struct Statistics
|
|||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire,
|
||||
mozilla::recordreplay::Behavior::DontPreserve>> counts;
|
||||
|
||||
/*
|
||||
* These events cannot be kept in the above array, we need to take their
|
||||
* address.
|
||||
*/
|
||||
struct {
|
||||
uint32_t nursery;
|
||||
uint32_t tenured;
|
||||
} allocsSinceMinorGC;
|
||||
|
||||
/* Allocated space before the GC started. */
|
||||
size_t preBytes;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ JS::Zone::Zone(JSRuntime* rt)
|
|||
uniqueIds_(this),
|
||||
suppressAllocationMetadataBuilder(this, false),
|
||||
arenas(this),
|
||||
tenuredAllocsSinceMinorGC_(0),
|
||||
types(this),
|
||||
gcWeakMapList_(this),
|
||||
compartments_(),
|
||||
|
|
|
@ -340,6 +340,19 @@ class Zone : public JS::shadow::Zone,
|
|||
|
||||
js::gc::ArenaLists arenas;
|
||||
|
||||
private:
|
||||
// Number of allocations since the most recent minor GC for this thread.
|
||||
mozilla::Atomic<uint32_t, mozilla::Relaxed> tenuredAllocsSinceMinorGC_;
|
||||
|
||||
public:
|
||||
void addTenuredAllocsSinceMinorGC(uint32_t allocs) {
|
||||
tenuredAllocsSinceMinorGC_ += allocs;
|
||||
}
|
||||
|
||||
uint32_t getAndResetTenuredAllocsSinceMinorGC() {
|
||||
return tenuredAllocsSinceMinorGC_.exchange(0);
|
||||
}
|
||||
|
||||
js::TypeZone types;
|
||||
|
||||
private:
|
||||
|
|
|
@ -214,6 +214,12 @@ CompileZone::addressOfStringNurseryCurrentEnd()
|
|||
return zone()->runtimeFromAnyThread()->gc.addressOfStringNurseryCurrentEnd();
|
||||
}
|
||||
|
||||
uint32_t*
|
||||
CompileZone::addressOfNurseryAllocCount()
|
||||
{
|
||||
return zone()->runtimeFromAnyThread()->gc.addressOfNurseryAllocCount();
|
||||
}
|
||||
|
||||
bool
|
||||
CompileZone::canNurseryAllocateStrings()
|
||||
{
|
||||
|
|
|
@ -82,6 +82,8 @@ class CompileZone
|
|||
const void* addressOfNurseryCurrentEnd();
|
||||
const void* addressOfStringNurseryCurrentEnd();
|
||||
|
||||
uint32_t* addressOfNurseryAllocCount();
|
||||
|
||||
bool nurseryExists();
|
||||
bool canNurseryAllocateStrings();
|
||||
void setMinorGCShouldCancelIonCompilations();
|
||||
|
|
|
@ -831,6 +831,12 @@ MacroAssembler::freeListAllocate(Register result, Register temp, gc::AllocKind a
|
|||
Pop(result);
|
||||
|
||||
bind(&success);
|
||||
|
||||
if (GetJitContext()->cx) {
|
||||
uint32_t* countAddress = GetJitContext()->cx->addressOfTenuredAllocCount();
|
||||
movePtr(ImmPtr(countAddress), temp);
|
||||
add32(Imm32(1), Address(temp, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -993,6 +999,17 @@ MacroAssembler::bumpPointerAllocate(Register result, Register temp, Label* fail,
|
|||
branchPtr(Assembler::Below, Address(temp, endOffset.value()), result, fail);
|
||||
storePtr(result, Address(temp, 0));
|
||||
subPtr(Imm32(size), result);
|
||||
|
||||
CompileZone* zone = GetJitContext()->realm->zone();
|
||||
uint32_t* countAddress = zone->addressOfNurseryAllocCount();
|
||||
CheckedInt<int32_t> counterOffset = (CheckedInt<uintptr_t>(uintptr_t(countAddress)) -
|
||||
CheckedInt<uintptr_t>(uintptr_t(posAddr))).toChecked<int32_t>();
|
||||
if (counterOffset.isValid()) {
|
||||
add32(Imm32(1), Address(temp, counterOffset.value()));
|
||||
} else {
|
||||
movePtr(ImmPtr(countAddress), temp);
|
||||
add32(Imm32(1), Address(temp, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Inlined equivalent of gc::AllocateString, jumping to fail if nursery
|
||||
|
|
|
@ -422,6 +422,11 @@ JSContext::enterAtomsZone()
|
|||
inline void
|
||||
JSContext::setZone(js::Zone *zone, JSContext::IsAtomsZone isAtomsZone)
|
||||
{
|
||||
if (zone_)
|
||||
zone_->addTenuredAllocsSinceMinorGC(allocsThisZoneSinceMinorGC_);
|
||||
|
||||
allocsThisZoneSinceMinorGC_ = 0;
|
||||
|
||||
zone_ = zone;
|
||||
if (zone == nullptr) {
|
||||
freeLists_ = nullptr;
|
||||
|
|
|
@ -130,6 +130,11 @@ struct JSContext : public JS::RootingContext,
|
|||
// Free lists for allocating in the current zone.
|
||||
js::ThreadData<js::gc::FreeLists*> freeLists_;
|
||||
|
||||
// This is reset each time we switch zone, then added to the variable in the
|
||||
// zone when we switch away from it. This would be a js::ThreadData but we
|
||||
// need to take its address.
|
||||
uint32_t allocsThisZoneSinceMinorGC_;
|
||||
|
||||
// Free lists for parallel allocation in the atoms zone on helper threads.
|
||||
js::ThreadData<js::gc::FreeLists*> atomsZoneFreeLists_;
|
||||
|
||||
|
@ -198,6 +203,20 @@ struct JSContext : public JS::RootingContext,
|
|||
js::ReportAllocationOverflow(this);
|
||||
}
|
||||
|
||||
void noteTenuredAlloc() {
|
||||
allocsThisZoneSinceMinorGC_++;
|
||||
}
|
||||
|
||||
uint32_t* addressOfTenuredAllocCount() {
|
||||
return &allocsThisZoneSinceMinorGC_;
|
||||
}
|
||||
|
||||
uint32_t getAndResetAllocsThisZoneSinceMinorGC() {
|
||||
uint32_t allocs = allocsThisZoneSinceMinorGC_;
|
||||
allocsThisZoneSinceMinorGC_ = 0;
|
||||
return allocs;
|
||||
}
|
||||
|
||||
// Accessors for immutable runtime data.
|
||||
JSAtomState& names() { return *runtime_->commonNames; }
|
||||
js::StaticStrings& staticStrings() { return *runtime_->staticStrings; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче