Bug 1657206 - Call RateMyCacheIR with one script, but spew multiple scripts from the same StructuredSpewer. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D90750
This commit is contained in:
Caroline Cullen 2020-09-22 18:36:24 +00:00
Родитель 0d9c3f79b6
Коммит e69342d551
3 изменённых файлов: 46 добавлений и 59 удалений

Просмотреть файл

@ -138,62 +138,49 @@ CacheIRHealth::Happiness CacheIRHealth::spewJSOpAndCacheIRHealth(
return entryHappiness;
}
bool CacheIRHealth::rateMyCacheIR(JSContext* cx, Handle<ScriptVector> scripts) {
AutoStructuredSpewer spew(cx, SpewChannel::RateMyCacheIR, nullptr);
bool CacheIRHealth::rateMyCacheIR(JSContext* cx, HandleScript script) {
AutoStructuredSpewer spew(cx, SpewChannel::RateMyCacheIR, script);
if (!spew) {
return true;
}
spew->beginListProperty("scripts");
for (uint32_t i = 0; i < scripts.length(); i++) {
Happiness scriptHappiness = Happy;
spew->beginObject();
{
HandleScript script = scripts[i];
jit::JitScript* jitScript = script->jitScript();
jsbytecode* next = script->code();
jsbytecode* end = script->codeEnd();
jit::JitScript* jitScript = script->jitScript();
jsbytecode* next = script->code();
jsbytecode* end = script->codeEnd();
spew->property("filename", script->filename());
spew->property("line", script->lineno());
spew->property("column", script->column());
spew->beginListProperty("entries");
ICEntry* prevEntry = nullptr;
Happiness scriptHappiness = Happy;
while (next < end) {
uint32_t len = 0;
uint32_t pcOffset = script->pcToOffset(next);
spew->beginListProperty("entries");
ICEntry* prevEntry = nullptr;
while (next < end) {
uint32_t len = 0;
uint32_t pcOffset = script->pcToOffset(next);
jit::ICEntry* entry =
jitScript->maybeICEntryFromPCOffset(pcOffset, prevEntry);
if (entry) {
prevEntry = entry;
}
JSOp op = JSOp(*next);
const JSCodeSpec& cs = CodeSpec(op);
len = cs.length;
MOZ_ASSERT(len);
if (entry && (entry->firstStub()->isFallback() ||
ICStub::IsCacheIRKind(entry->firstStub()->kind()))) {
Happiness entryHappiness =
spewJSOpAndCacheIRHealth(spew, script, entry, next, op);
if (entryHappiness < scriptHappiness) {
scriptHappiness = entryHappiness;
}
}
next += len;
}
spew->endList(); // entries
spew->property("scriptHappiness", uint8_t(scriptHappiness));
jit::ICEntry* entry =
jitScript->maybeICEntryFromPCOffset(pcOffset, prevEntry);
if (entry) {
prevEntry = entry;
}
spew->endObject();
JSOp op = JSOp(*next);
const JSCodeSpec& cs = CodeSpec(op);
len = cs.length;
MOZ_ASSERT(len);
if (entry && (entry->firstStub()->isFallback() ||
ICStub::IsCacheIRKind(entry->firstStub()->kind()))) {
Happiness entryHappiness =
spewJSOpAndCacheIRHealth(spew, script, entry, next, op);
if (entryHappiness < scriptHappiness) {
scriptHappiness = entryHappiness;
}
}
next += len;
}
spew->endList(); // scripts
spew->endList(); // entries
spew->property("scriptHappiness", uint8_t(scriptHappiness));
return true;
}

Просмотреть файл

@ -54,7 +54,7 @@ class CacheIRHealth {
jsbytecode* pc, JSOp op);
// If a JitScript exists, shows health of all ICEntries that exist
// for the specified script.
bool rateMyCacheIR(JSContext* cx, Handle<ScriptVector> scripts);
bool rateMyCacheIR(JSContext* cx, HandleScript script);
};
} // namespace jit

Просмотреть файл

@ -3644,8 +3644,9 @@ static bool DisassWithSrc(JSContext* cx, unsigned argc, Value* vp) {
#ifdef JS_CACHEIR_SPEW
static bool RateMyCacheIR(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<ScriptVector> scripts(cx, ScriptVector(cx));
js::jit::CacheIRHealth cih;
RootedScript script(cx);
if (!argc) {
// Calling RateMyCacheIR without any arguments will create health
// reports for all scripts in the zone.
@ -3655,28 +3656,27 @@ static bool RateMyCacheIR(JSContext* cx, unsigned argc, Value* vp) {
continue;
}
if (!scripts.append(base->asJSScript())) {
script = base->asJSScript();
if (!cih.rateMyCacheIR(cx, script)) {
return false;
}
}
} else {
RootedValue value(cx, args.get(0));
RootedScript script(cx);
if (value.isObject() && value.toObject().is<ModuleObject>()) {
script.set(value.toObject().as<ModuleObject>().maybeScript());
script = value.toObject().as<ModuleObject>().maybeScript();
} else {
script.set(TestingFunctionArgumentToScript(cx, args.get(0)));
script = TestingFunctionArgumentToScript(cx, args.get(0));
}
if (!script || !scripts.append(script)) {
if (!script) {
return false;
}
}
js::jit::CacheIRHealth cih;
if (!cih.rateMyCacheIR(cx, scripts)) {
return false;
if (!cih.rateMyCacheIR(cx, script)) {
return false;
}
}
args.rval().setUndefined();