add dumpJIT() to disassemble

This is yet another debug tool there to help me on
machines that I can't profile with perf or vtune.

Reorganize debug hooks in SkVMBlitter a little.

Disabled on Windows... no llvm-mc, popen, or memmem.

Change-Id: I56d01a6df494aae126c66b9558f57b7449124c95
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/264478
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Mike Klein 2020-01-14 15:47:03 -06:00 committed by Skia Commit-Bot
parent 42032cb88f
commit cb67acbab4
3 changed files with 27 additions and 14 deletions

View File

@ -377,6 +377,23 @@ namespace skvm {
}
}
void Program::dumpJIT() const {
#if !defined(SK_BUILD_FOR_WIN)
// Disassemble up through vzeroupper, retq exit. No need for constants or zero padding.
const uint8_t vzeroupper_retq[] = { 0xc5, 0xf8, 0x77, 0xc3 };
auto end = (const uint8_t*)memmem(fJITBuf, fJITSize,
vzeroupper_retq, SK_ARRAY_COUNT(vzeroupper_retq));
SkASSERT(end);
end += SK_ARRAY_COUNT(vzeroupper_retq);
FILE* p = popen("llvm-mc --disassemble --no-warn", "w");
for (auto buf = (const uint8_t*)fJITBuf; buf != end; buf++) {
fprintf(p, "0x%02x\n", *buf);
}
pclose(p);
#endif
}
// Builder -> Program, with liveness and loop hoisting analysis.
Program Builder::done(const char* debug_name) {

View File

@ -635,6 +635,7 @@ namespace skvm {
bool hasJIT() const; // Has this Program been JITted?
void dropJIT(); // If hasJIT(), drop it, forcing interpreter fallback.
void dumpJIT() const; // Disassemble to stdout.
void dump(SkWStream* = nullptr) const;

View File

@ -86,15 +86,6 @@ namespace {
key.shader);
}
static bool debug_dump(const Key& key) {
#if 0
SkDebugf("%s\n", debug_name(key).c_str());
return true;
#else
return false;
#endif
}
static SkLRUCache<Key, skvm::Program>* try_acquire_program_cache() {
#if 0 || defined(SK_BUILD_FOR_IOS)
// iOS doesn't support thread_local on versions less than 9.0. pthread
@ -465,16 +456,20 @@ namespace {
SkASSERT(fUniforms.buf.size() == prev);
skvm::Program program = builder.done(debug_name(key).c_str());
if (debug_dump(key)) {
if (false) {
static std::atomic<int> done{0};
if (0 == done++) {
atexit([]{ SkDebugf("%d calls to done\n", done.load()); });
}
if (!program.hasJIT()) {
SkDebugf("\nfalling back to interpreter for blitter with this key.\n");
builder.dump();
program.dump();
SkDebugf("%s\n", debug_name(key).c_str());
builder.dump();
program.dump();
if (program.hasJIT()) {
program.dumpJIT();
} else {
SkDebugf("\nfell back to interpreter for blitter with this key.\n");
}
}
return program;