test both JIT and interpreter
Add Program::dropJIT() to allow us to proactively drop
any JIT code forcing fallback on the interpreter,
and use it to test both on JIT-supported platforms.
Other platforms will just test the interpreter twice.
Change-Id: I607d00ef3c648e66a0b3a1374b11aa82dbfff70c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227424
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Herb Derby <herb@google.com>
diff --git a/src/core/SkVM.cpp b/src/core/SkVM.cpp
index f459c5e..66a611c 100644
--- a/src/core/SkVM.cpp
+++ b/src/core/SkVM.cpp
@@ -1436,7 +1436,7 @@
}
}
- Program::~Program() {
+ void Program::dropJIT() {
#if defined(SKVM_JIT)
if (fJITBuf) {
munmap(fJITBuf, fJITSize);
@@ -1444,8 +1444,14 @@
#else
SkASSERT(fJITBuf == nullptr);
#endif
+
+ fJITBuf = nullptr;
+ fJITSize = 0;
+ fJITEntry = nullptr;
}
+ Program::~Program() { this->dropJIT(); }
+
Program::Program(Program&& other) {
fInstructions = std::move(other.fInstructions);
fRegs = other.fRegs;
diff --git a/src/core/SkVM.h b/src/core/SkVM.h
index 3f56166..2f97c71 100644
--- a/src/core/SkVM.h
+++ b/src/core/SkVM.h
@@ -268,6 +268,9 @@
int nregs() const { return fRegs; }
int loop() const { return fLoop; }
+ // If this Program has been JITted, drop it, forcing interpreter fallback.
+ void dropJIT();
+
private:
void eval(int n, void* args[]) const;
diff --git a/tests/SkVMTest.cpp b/tests/SkVMTest.cpp
index 1291f67..ad01f47 100644
--- a/tests/SkVMTest.cpp
+++ b/tests/SkVMTest.cpp
@@ -200,6 +200,12 @@
} // namespace
+template <typename Fn>
+static void test_jit_and_interpreter(skvm::Program&& program, Fn&& test) {
+ test((const skvm::Program&) program);
+ program.dropJIT();
+ test((const skvm::Program&) program);
+}
DEF_TEST(SkVM, r) {
SkDynamicMemoryWStream buf;
@@ -260,30 +266,32 @@
}
}
- auto test_8888 = [&](const skvm::Program& program) {
+ auto test_8888 = [&](skvm::Program&& program) {
uint32_t src[9];
uint32_t dst[SK_ARRAY_COUNT(src)];
- for (int i = 0; i < (int)SK_ARRAY_COUNT(src); i++) {
- src[i] = 0xbb007733;
- dst[i] = 0xffaaccee;
- }
-
- SkPMColor expected = SkPMSrcOver(src[0], dst[0]); // 0xff2dad73
-
- program.eval((int)SK_ARRAY_COUNT(src), src, dst);
-
- // dst is probably 0xff2dad72.
- for (auto got : dst) {
- auto want = expected;
- for (int i = 0; i < 4; i++) {
- uint8_t d = got & 0xff,
- w = want & 0xff;
- REPORTER_ASSERT(r, abs(d-w) < 2);
- got >>= 8;
- want >>= 8;
+ test_jit_and_interpreter(std::move(program), [&](const skvm::Program& program) {
+ for (int i = 0; i < (int)SK_ARRAY_COUNT(src); i++) {
+ src[i] = 0xbb007733;
+ dst[i] = 0xffaaccee;
}
- }
+
+ SkPMColor expected = SkPMSrcOver(src[0], dst[0]); // 0xff2dad73
+
+ program.eval((int)SK_ARRAY_COUNT(src), src, dst);
+
+ // dst is probably 0xff2dad72.
+ for (auto got : dst) {
+ auto want = expected;
+ for (int i = 0; i < 4; i++) {
+ uint8_t d = got & 0xff,
+ w = want & 0xff;
+ REPORTER_ASSERT(r, abs(d-w) < 2);
+ got >>= 8;
+ want >>= 8;
+ }
+ }
+ });
};
test_8888(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::RGBA_8888}.done());
@@ -291,9 +299,8 @@
test_8888(SrcoverBuilder_I32{}.done());
test_8888(SrcoverBuilder_I32_SWAR{}.done());
- {
- skvm::Program program = SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done();
-
+ test_jit_and_interpreter(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done(),
+ [&](const skvm::Program& program) {
uint32_t src[9];
uint8_t dst[SK_ARRAY_COUNT(src)];
@@ -313,11 +320,10 @@
for (auto got : dst) {
REPORTER_ASSERT(r, abs(got-want) < 3);
}
- }
+ });
- {
- skvm::Program program = SrcoverBuilder_F32{Fmt::A8, Fmt::A8}.done();
-
+ test_jit_and_interpreter(SrcoverBuilder_F32{Fmt::A8, Fmt::A8}.done(),
+ [&](const skvm::Program& program) {
uint8_t src[256],
dst[256];
for (int i = 0; i < 256; i++) {
@@ -332,36 +338,34 @@
SkPackARGB32( i, 0,0,0)));
REPORTER_ASSERT(r, abs(dst[i]-want) < 2);
}
- }
+ });
}
DEF_TEST(SkVM_LoopCounts, r) {
// Make sure we cover all the exact N we want.
+ // buf[i] += 1
+ skvm::Builder b;
+ skvm::Arg arg = b.arg<int>();
+ b.store32(arg,
+ b.add(b.splat(1),
+ b.load32(arg)));
+
int buf[64];
for (int N = 0; N <= (int)SK_ARRAY_COUNT(buf); N++) {
- for (int i = 0; i < (int)SK_ARRAY_COUNT(buf); i++) {
- buf[i] = i;
- }
+ test_jit_and_interpreter(b.done(), [&](const skvm::Program& program) {
+ for (int i = 0; i < (int)SK_ARRAY_COUNT(buf); i++) {
+ buf[i] = i;
+ }
+ program.eval(N, buf);
-
- // buf[i] += 1
- skvm::Builder b;
- skvm::Arg arg = b.arg<int>();
-
- b.store32(arg,
- b.add(b.splat(1),
- b.load32(arg)));
-
- skvm::Program program = b.done();
- program.eval(N, buf);
-
- for (int i = 0; i < N; i++) {
- REPORTER_ASSERT(r, buf[i] == i+1);
- }
- for (int i = N; i < (int)SK_ARRAY_COUNT(buf); i++) {
- REPORTER_ASSERT(r, buf[i] == i);
- }
+ for (int i = 0; i < N; i++) {
+ REPORTER_ASSERT(r, buf[i] == i+1);
+ }
+ for (int i = N; i < (int)SK_ARRAY_COUNT(buf); i++) {
+ REPORTER_ASSERT(r, buf[i] == i);
+ }
+ });
}
}