diff options
author | Alon Zakai <azakai@google.com> | 2020-06-12 17:15:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-12 17:15:22 -0700 |
commit | d26f90bba43c1672232f51bc90c8194a31aea065 (patch) | |
tree | 48b7504b2b5e46dec3a8a7fb290e82314ddf6344 /test | |
parent | 49f2443338c00931d2f30f9d8c1706398bd5cb34 (diff) | |
download | binaryen-d26f90bba43c1672232f51bc90c8194a31aea065.tar.gz binaryen-d26f90bba43c1672232f51bc90c8194a31aea065.tar.bz2 binaryen-d26f90bba43c1672232f51bc90c8194a31aea065.zip |
Asyncify: Add an "add list", rename old lists (#2910)
Asyncify does a whole-program analysis to figure out the list of functions
to instrument. In
emscripten-core/emscripten#10746 (comment)
we realized that we need another type of list there, an "add list" which is a
list of functions to add to the instrumented functions list, that is, that we
should definitely instrument.
The use case in that link is that we disable indirect calls, but there is
one special indirect call that we do need to instrument. Being able to add
just that one can be much more efficient than assuming all indirect calls in
a big codebase need instrumentation. Similar issues can come up if we
add a profile-guided option to asyncify, which we've discussed.
The existing lists were not good enough to allow that, so a new option
is needed. I took the opportunity to rename the old ones to something
better and more consistent, so after this PR we have 3 lists as follows:
* The old "remove list" (previously "blacklist") which removes functions
from the list of functions to be instrumented.
* The new "add list" which adds to that list (note how add/remove are
clearly parallel).
* The old "only list" (previously "whitelist") which simply replaces the
entire list, and so only those functions are instrumented and no other.
This PR temporarily still supports the old names in the commandline
arguments, to avoid immediate breakage for our CI.
Diffstat (limited to 'test')
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-addlist@foo.txt | 162 | ||||
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-addlist@foo.wast | 13 | ||||
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.txt (renamed from test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.txt) | 0 | ||||
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast (renamed from test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.wast) | 0 | ||||
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.txt (renamed from test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.txt) | 0 | ||||
-rw-r--r-- | test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast (renamed from test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.wast) | 2 | ||||
-rw-r--r-- | test/unit/test_asyncify.py | 38 |
7 files changed, 199 insertions, 16 deletions
diff --git a/test/passes/asyncify_pass-arg=asyncify-addlist@foo.txt b/test/passes/asyncify_pass-arg=asyncify-addlist@foo.txt new file mode 100644 index 000000000..8119cfc6a --- /dev/null +++ b/test/passes/asyncify_pass-arg=asyncify-addlist@foo.txt @@ -0,0 +1,162 @@ +(module + (type $none_=>_none (func)) + (type $i32_=>_none (func (param i32))) + (type $none_=>_i32 (func (result i32))) + (import "env" "import" (func $import)) + (memory $0 1 2) + (global $__asyncify_state (mut i32) (i32.const 0)) + (global $__asyncify_data (mut i32) (i32.const 0)) + (export "asyncify_start_unwind" (func $asyncify_start_unwind)) + (export "asyncify_stop_unwind" (func $asyncify_stop_unwind)) + (export "asyncify_start_rewind" (func $asyncify_start_rewind)) + (export "asyncify_stop_rewind" (func $asyncify_stop_rewind)) + (export "asyncify_get_state" (func $asyncify_get_state)) + (func $foo + (local $0 i32) + (local $1 i32) + (if + (i32.eq + (global.get $__asyncify_state) + (i32.const 2) + ) + (nop) + ) + (local.tee $0 + (block $__asyncify_unwind + (block + (block + (if + (i32.eq + (global.get $__asyncify_state) + (i32.const 2) + ) + (block + (i32.store + (global.get $__asyncify_data) + (i32.add + (i32.load + (global.get $__asyncify_data) + ) + (i32.const -4) + ) + ) + (local.set $1 + (i32.load + (i32.load + (global.get $__asyncify_data) + ) + ) + ) + ) + ) + (if + (i32.eq + (global.get $__asyncify_state) + (i32.const 0) + ) + (call $nothing) + ) + ) + (return) + ) + ) + ) + (block + (i32.store + (i32.load + (global.get $__asyncify_data) + ) + (local.get $0) + ) + (i32.store + (global.get $__asyncify_data) + (i32.add + (i32.load + (global.get $__asyncify_data) + ) + (i32.const 4) + ) + ) + ) + (nop) + ) + (func $bar + (call $nothing) + ) + (func $nothing + (nop) + ) + (func $asyncify_start_unwind (param $0 i32) + (global.set $__asyncify_state + (i32.const 1) + ) + (global.set $__asyncify_data + (local.get $0) + ) + (if + (i32.gt_u + (i32.load + (global.get $__asyncify_data) + ) + (i32.load offset=4 + (global.get $__asyncify_data) + ) + ) + (unreachable) + ) + ) + (func $asyncify_stop_unwind + (global.set $__asyncify_state + (i32.const 0) + ) + (if + (i32.gt_u + (i32.load + (global.get $__asyncify_data) + ) + (i32.load offset=4 + (global.get $__asyncify_data) + ) + ) + (unreachable) + ) + ) + (func $asyncify_start_rewind (param $0 i32) + (global.set $__asyncify_state + (i32.const 2) + ) + (global.set $__asyncify_data + (local.get $0) + ) + (if + (i32.gt_u + (i32.load + (global.get $__asyncify_data) + ) + (i32.load offset=4 + (global.get $__asyncify_data) + ) + ) + (unreachable) + ) + ) + (func $asyncify_stop_rewind + (global.set $__asyncify_state + (i32.const 0) + ) + (if + (i32.gt_u + (i32.load + (global.get $__asyncify_data) + ) + (i32.load offset=4 + (global.get $__asyncify_data) + ) + ) + (unreachable) + ) + ) + (func $asyncify_get_state (result i32) + (global.get $__asyncify_state) + ) +) diff --git a/test/passes/asyncify_pass-arg=asyncify-addlist@foo.wast b/test/passes/asyncify_pass-arg=asyncify-addlist@foo.wast new file mode 100644 index 000000000..beb89a66a --- /dev/null +++ b/test/passes/asyncify_pass-arg=asyncify-addlist@foo.wast @@ -0,0 +1,13 @@ +(module + (memory 1 2) + (import "env" "import" (func $import)) + (func $foo ;; doesn't look like it needs instrumentation, but in add list + (call $nothing) + ) + (func $bar ;; doesn't look like it needs instrumentation, and not in add list + (call $nothing) + ) + (func $nothing + ) +) + diff --git a/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.txt b/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.txt index 08eda7a63..08eda7a63 100644 --- a/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.txt +++ b/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.txt diff --git a/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.wast b/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast index 7d67c89ed..7d67c89ed 100644 --- a/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-whitelist@waka.wast +++ b/test/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast diff --git a/test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.txt b/test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.txt index 30d4f0f10..30d4f0f10 100644 --- a/test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.txt +++ b/test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.txt diff --git a/test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.wast b/test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast index 355ca1b11..a152a5376 100644 --- a/test/passes/asyncify_pass-arg=asyncify-whitelist@foo,bar.wast +++ b/test/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast @@ -11,7 +11,7 @@ (call $import) ) (func $other1 - (call $foo) ;; even though we call foo, we are not in the whitelist, so do not instrument us + (call $foo) ;; even though we call foo, we are not in the only list, so do not instrument us ) (func $other2 (call $baz) diff --git a/test/unit/test_asyncify.py b/test/unit/test_asyncify.py index 331e1a9e2..55b198cbb 100644 --- a/test/unit/test_asyncify.py +++ b/test/unit/test_asyncify.py @@ -41,17 +41,17 @@ class AsyncifyTest(utils.BinaryenTestCase): def test_asyncify_list_bad(self): for arg, warning in [ - ('--pass-arg=asyncify-blacklist@nonexistent', 'nonexistent'), - ('--pass-arg=asyncify-whitelist@nonexistent', 'nonexistent'), - ('--pass-arg=asyncify-blacklist@main', None), - ('--pass-arg=asyncify-whitelist@main', None), - ('--pass-arg=asyncify-blacklist@m*n', None), - ('--pass-arg=asyncify-whitelist@m*n', None), - ('--pass-arg=asyncify-whitelist@main*', None), - ('--pass-arg=asyncify-whitelist@*main', None), - ('--pass-arg=asyncify-blacklist@non*existent', 'non*existent'), - ('--pass-arg=asyncify-whitelist@non*existent', 'non*existent'), - ('--pass-arg=asyncify-whitelist@DOS_ReadFile(unsigned short, unsigned char*, unsigned short*, bool)', None), + ('--pass-arg=asyncify-removelist@nonexistent', 'nonexistent'), + ('--pass-arg=asyncify-onlylist@nonexistent', 'nonexistent'), + ('--pass-arg=asyncify-removelist@main', None), + ('--pass-arg=asyncify-onlylist@main', None), + ('--pass-arg=asyncify-removelist@m*n', None), + ('--pass-arg=asyncify-onlylist@m*n', None), + ('--pass-arg=asyncify-onlylist@main*', None), + ('--pass-arg=asyncify-onlylist@*main', None), + ('--pass-arg=asyncify-removelist@non*existent', 'non*existent'), + ('--pass-arg=asyncify-onlylist@non*existent', 'non*existent'), + ('--pass-arg=asyncify-onlylist@DOS_ReadFile(unsigned short, unsigned char*, unsigned short*, bool)', None), ]: print(arg, warning) err = shared.run_process(shared.WASM_OPT + ['-q', self.input_path('asyncify-pure.wat'), '--asyncify', arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.strip() @@ -61,10 +61,18 @@ class AsyncifyTest(utils.BinaryenTestCase): else: self.assertNotIn('warning', err) - def test_asyncify_blacklist_and_whitelist(self): - proc = shared.run_process(shared.WASM_OPT + [self.input_path('asyncify-pure.wat'), '--asyncify', '--pass-arg=asyncify-whitelist@main', '--pass-arg=asyncify-blacklist@main'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - self.assertNotEqual(proc.returncode, 0, 'must error on using both lists at once') - self.assertIn('It makes no sense to use both a blacklist and a whitelist with asyncify', proc.stdout) + def test_asyncify_onlylist_and_other(self): + def test(list_name): + args = shared.WASM_OPT + [self.input_path('asyncify-pure.wat'), + '--asyncify', + '--pass-arg=asyncify-onlylist@main', + '--pass-arg=asyncify-%slist@main' % list_name] + proc = shared.run_process(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + self.assertNotEqual(proc.returncode, 0, 'must error on using both lists at once') + self.assertIn('It makes no sense to use both an asyncify only-list together with another list', proc.stdout) + + test('remove') + test('add') def test_asyncify_imports(self): def test(args): |