mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1672787 - Part 9: Spew final warm up count during finalization. r=iain
Differential Revision: https://phabricator.services.mozilla.com/D98668
This commit is contained in:
parent
bdcd0d89be
commit
119e260dbc
@ -8069,6 +8069,9 @@ void GCRuntime::mergeRealms(Realm* source, Realm* target) {
|
||||
#ifdef MOZ_VTUNE
|
||||
MOZ_ASSERT(!sourceZone->scriptVTuneIdMap);
|
||||
#endif
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
MOZ_ASSERT(!sourceZone->scriptFinalWarmUpCountMap);
|
||||
#endif
|
||||
|
||||
// The source realm is now completely empty, and is the only realm in its
|
||||
// compartment, which is the only compartment in its zone. Delete realm,
|
||||
|
@ -438,6 +438,10 @@ void Zone::discardJitCode(JSFreeOp* fop,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
maybeUpdateWarmUpCount(script);
|
||||
#endif
|
||||
|
||||
// Warm-up counter for scripts are reset on GC. After discarding code we
|
||||
// need to let it warm back up to get information such as which
|
||||
// opcodes are setting array holes or accessing getter properties.
|
||||
@ -849,6 +853,19 @@ void Zone::fixupScriptMapsAfterMovingGC(JSTracer* trc) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
if (scriptFinalWarmUpCountMap) {
|
||||
for (ScriptFinalWarmUpCountMap::Enum e(*scriptFinalWarmUpCountMap);
|
||||
!e.empty(); e.popFront()) {
|
||||
BaseScript* script = e.front().key();
|
||||
if (!IsAboutToBeFinalizedUnbarriered(&script) &&
|
||||
script != e.front().key()) {
|
||||
e.rekeyFront(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
@ -896,6 +913,18 @@ void Zone::checkScriptMapsAfterMovingGC() {
|
||||
}
|
||||
}
|
||||
# endif // MOZ_VTUNE
|
||||
|
||||
# ifdef JS_CACHEIR_SPEW
|
||||
if (scriptFinalWarmUpCountMap) {
|
||||
for (auto r = scriptFinalWarmUpCountMap->all(); !r.empty(); r.popFront()) {
|
||||
BaseScript* script = r.front().key();
|
||||
MOZ_ASSERT(script->zone() == this);
|
||||
CheckGCThingAfterMovingGC(script);
|
||||
auto ptr = scriptFinalWarmUpCountMap->lookup(script);
|
||||
MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
|
||||
}
|
||||
}
|
||||
# endif // JS_CACHEIR_SPEW
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -223,6 +223,9 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
|
||||
#ifdef MOZ_VTUNE
|
||||
js::UniquePtr<js::ScriptVTuneIdMap> scriptVTuneIdMap;
|
||||
#endif
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
js::UniquePtr<js::ScriptFinalWarmUpCountMap> scriptFinalWarmUpCountMap;
|
||||
#endif
|
||||
|
||||
js::ZoneData<js::StringStats> previousGCStringStats;
|
||||
js::ZoneData<js::StringStats> stringStats;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
# include "mozilla/Maybe.h"
|
||||
|
||||
# include "gc/Zone.h"
|
||||
# include "jit/JitScript.h"
|
||||
|
||||
using namespace js;
|
||||
@ -151,6 +152,35 @@ void CacheIRHealth::spewScriptFinalWarmUpCount(JSContext* cx,
|
||||
spew->property("finalWarmUpCount", warmUpCount);
|
||||
}
|
||||
|
||||
static void addScriptToFinalWarmUpCountMap(JSContext* cx, HandleScript script) {
|
||||
// Create Zone::scriptFilenameMap if necessary.
|
||||
JS::Zone* zone = script->zone();
|
||||
if (!zone->scriptFinalWarmUpCountMap) {
|
||||
auto map = MakeUnique<ScriptFinalWarmUpCountMap>();
|
||||
if (!map) {
|
||||
ReportOutOfMemory(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
zone->scriptFinalWarmUpCountMap = std::move(map);
|
||||
}
|
||||
|
||||
auto* filename = js_pod_malloc<char>(strlen(script->filename()) + 1);
|
||||
if (!filename) {
|
||||
ReportOutOfMemory(cx);
|
||||
return;
|
||||
}
|
||||
strcpy(filename, script->filename());
|
||||
|
||||
if (!zone->scriptFinalWarmUpCountMap->put(
|
||||
script, mozilla::MakeTuple(uint32_t(0), filename))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
script->setNeedsFinalWarmUpCount();
|
||||
}
|
||||
|
||||
void CacheIRHealth::rateIC(JSContext* cx, ICEntry* entry, HandleScript script,
|
||||
SpewContext context) {
|
||||
AutoStructuredSpewer spew(cx, SpewChannel::RateMyCacheIR, script);
|
||||
@ -158,7 +188,7 @@ void CacheIRHealth::rateIC(JSContext* cx, ICEntry* entry, HandleScript script,
|
||||
return;
|
||||
}
|
||||
|
||||
script->setNeedsFinalWarmUpCount();
|
||||
addScriptToFinalWarmUpCountMap(cx, script);
|
||||
spew->property("spewContext", uint8_t(context));
|
||||
|
||||
jsbytecode* op = entry->pc(script);
|
||||
@ -180,7 +210,7 @@ void CacheIRHealth::rateScript(JSContext* cx, HandleScript script,
|
||||
return;
|
||||
}
|
||||
|
||||
script->setNeedsFinalWarmUpCount();
|
||||
addScriptToFinalWarmUpCountMap(cx, script);
|
||||
spew->property("spewContext", uint8_t(context));
|
||||
|
||||
jsbytecode* next = script->code();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "frontend/StencilXdr.h" // frontend::StencilXdr::SharedData
|
||||
#include "gc/FreeOp.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/CacheIRHealth.h"
|
||||
#include "jit/Invalidation.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/IonScript.h"
|
||||
@ -646,9 +647,18 @@ void js::BaseScript::finalize(JSFreeOp* fop) {
|
||||
|
||||
if (warmUpData_.isJitScript()) {
|
||||
JSScript* script = this->asJSScript();
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
maybeUpdateWarmUpCount(script);
|
||||
#endif
|
||||
script->releaseJitScriptOnFinalize(fop);
|
||||
}
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
if (hasBytecode()) {
|
||||
maybeSpewScriptFinalWarmUpCount(this->asJSScript());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data_) {
|
||||
// We don't need to triger any barriers here, just free the memory.
|
||||
size_t size = data_->allocationSize();
|
||||
@ -4210,6 +4220,51 @@ JS_FRIEND_API unsigned js::GetScriptLineExtent(JSScript* script) {
|
||||
return 1 + maxLineNo - script->lineno();
|
||||
}
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
void js::maybeUpdateWarmUpCount(JSScript* script) {
|
||||
if (script->needsFinalWarmUpCount()) {
|
||||
ScriptFinalWarmUpCountMap* map =
|
||||
script->zone()->scriptFinalWarmUpCountMap.get();
|
||||
// If needsFinalWarmUpCount is true, ScriptFinalWarmUpCountMap must have
|
||||
// already been created and thus must be asserted.
|
||||
MOZ_ASSERT(map);
|
||||
ScriptFinalWarmUpCountMap::Ptr p = map->lookup(script);
|
||||
MOZ_ASSERT(p);
|
||||
|
||||
mozilla::Get<0>(p->value()) += script->jitScript()->warmUpCount();
|
||||
}
|
||||
}
|
||||
|
||||
void js::maybeSpewScriptFinalWarmUpCount(JSScript* script) {
|
||||
if (script->needsFinalWarmUpCount()) {
|
||||
ScriptFinalWarmUpCountMap* map =
|
||||
script->zone()->scriptFinalWarmUpCountMap.get();
|
||||
// If needsFinalWarmUpCount is true, ScriptFinalWarmUpCountMap must have
|
||||
// already been created and thus must be asserted.
|
||||
MOZ_ASSERT(map);
|
||||
ScriptFinalWarmUpCountMap::Ptr p = map->lookup(script);
|
||||
MOZ_ASSERT(p);
|
||||
uint32_t warmUpCount;
|
||||
const char* scriptName;
|
||||
mozilla::Tie(warmUpCount, scriptName) = p->value();
|
||||
|
||||
JSContext* cx = TlsContext.get();
|
||||
cx->spewer().enableSpewing();
|
||||
|
||||
// In the case that we care about a script's final warmup count but the
|
||||
// spewer is not enabled, AutoSpewChannel automatically sets and unsets
|
||||
// the proper channel for the duration of spewing a health report's warm
|
||||
// up count.
|
||||
AutoSpewChannel channel(cx, SpewChannel::RateMyCacheIR, script);
|
||||
jit::CacheIRHealth cih;
|
||||
cih.spewScriptFinalWarmUpCount(cx, scriptName, script, warmUpCount);
|
||||
|
||||
script->zone()->scriptFinalWarmUpCountMap->remove(script);
|
||||
script->setNeedsFinalWarmUpCount(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void js::DescribeScriptedCallerForDirectEval(JSContext* cx, HandleScript script,
|
||||
jsbytecode* pc, const char** file,
|
||||
unsigned* linenop,
|
||||
|
@ -174,6 +174,12 @@ using ScriptLCovMap = HashMap<BaseScript*, ScriptLCovEntry,
|
||||
using ScriptVTuneIdMap = HashMap<BaseScript*, uint32_t,
|
||||
DefaultHasher<BaseScript*>, SystemAllocPolicy>;
|
||||
#endif
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
using ScriptFinalWarmUpCountEntry = mozilla::Tuple<uint32_t, char*>;
|
||||
using ScriptFinalWarmUpCountMap =
|
||||
HashMap<BaseScript*, ScriptFinalWarmUpCountEntry,
|
||||
DefaultHasher<BaseScript*>, SystemAllocPolicy>;
|
||||
#endif
|
||||
|
||||
using UniqueDebugScript = js::UniquePtr<DebugScript, JS::FreePolicy>;
|
||||
using DebugScriptMap = HashMap<BaseScript*, UniqueDebugScript,
|
||||
@ -2436,6 +2442,11 @@ extern jsbytecode* LineNumberToPC(JSScript* script, unsigned lineno);
|
||||
|
||||
extern JS_FRIEND_API unsigned GetScriptLineExtent(JSScript* script);
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
void maybeUpdateWarmUpCount(JSScript* script);
|
||||
void maybeSpewScriptFinalWarmUpCount(JSScript* script);
|
||||
#endif
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace js {
|
||||
|
Loading…
Reference in New Issue
Block a user