make EMTERPRETIFY_ADVISE helpful regarding the yield list

This commit is contained in:
Alon Zakai 2015-03-20 16:13:22 -07:00
Родитель 03a1ad4f35
Коммит de7edde68a
3 изменённых файлов: 28 добавлений и 0 удалений

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

@ -632,6 +632,8 @@ var EMTERPRETIFY_ADVISE = 0; // Performs a static analysis to suggest which func
// appears they can be on the stack when a sync function is called in the EMTERPRETIFY_ASYNC option.
// After showing the suggested list, compilation will halt. You can apply the provided list as an
// emcc argument when compiling later.
// This will also advise on the YIELDLIST, if it contains at least one value (it then reports
// all things reachable from that function, as they may need to be in the YIELDLIST as well).
// Note that this depends on things like inlining. If you run this with different inlining than
// when you use the list, it might not work.

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

@ -4606,6 +4606,13 @@ function _main() {
out, err = Popen([PYTHON, EMCC, path_from_root('tests', 'emterpreter_advise_funcptr.cpp'), '-s', 'EMTERPRETIFY=1', '-s', 'EMTERPRETIFY_ASYNC=1', '-s', 'EMTERPRETIFY_ADVISE=1'], stdout=PIPE).communicate()
self.assertContained('-s EMTERPRETIFY_WHITELIST=\'["__Z4posti", "__Z5post2i", "__Z6middlev", "__Z7sleeperv", "__Z8recurserv", "_main"]\'', out)
self.assertNotContained('EMTERPRETIFY_YIELDLIST', out);
out, err = Popen([PYTHON, EMCC, path_from_root('tests', 'emterpreter_advise_funcptr.cpp'), '-s', 'EMTERPRETIFY=1', '-s', 'EMTERPRETIFY_ASYNC=1', '-s', 'EMTERPRETIFY_ADVISE=1', '-s', 'EMTERPRETIFY_YIELDLIST=["__Z6middlev"]'], stdout=PIPE).communicate()
self.assertContained('-s EMTERPRETIFY_YIELDLIST=\'["__Z6middlev", "__Z7siblingii", "__Z7sleeperv", "__Z8recurserv", "_printf"]\'', out)
out, err = Popen([PYTHON, EMCC, path_from_root('tests', 'emterpreter_advise_funcptr.cpp'), '-s', 'EMTERPRETIFY=1', '-s', 'EMTERPRETIFY_ASYNC=1', '-s', 'EMTERPRETIFY_ADVISE=1', '-s', 'EMTERPRETIFY_YIELDLIST=["__Z3pref"]'], stdout=PIPE).communicate()
self.assertContained('-s EMTERPRETIFY_YIELDLIST=\'["__Z3pref", "__Z7siblingii", "_printf"]\'', out)
def test_link_with_a_static(self):
for args in [[], ['-O2']]:

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

@ -706,6 +706,8 @@ if __name__ == '__main__':
outfile = sys.argv[2]
force_memfile = sys.argv[3] if len(sys.argv) >= 4 else None
original_yieldlist = YIELDLIST
extra_blacklist = []
if len(sys.argv) >= 5:
temp = sys.argv[4]
@ -775,6 +777,23 @@ if __name__ == '__main__':
print "Suggested list of functions to run in the emterpreter:"
print " -s EMTERPRETIFY_WHITELIST='" + str(sorted(list(advised))).replace("'", '"') + "'"
print "(%d%% out of %d functions)" % (int((100.0*len(advised))/len(can_call)), len(can_call))
if len(YIELDLIST) > len(original_yieldlist):
# advise on the yield list as well. Anything a yield function can reach, likely needs to also be a yield function
YIELD_IGNORE = set(['abort'])
to_check = list(YIELDLIST)
advised = set([str(f) for f in YIELDLIST])
while len(to_check) > 0:
curr = to_check.pop()
if curr not in can_call: continue
for next in can_call[curr]:
if next not in advised:
advised.add(str(next))
to_check.append(next)
advised = [next for next in advised if not is_dyn_call(next) and not is_function_table(next) and not next in original_yieldlist and next not in SYNC_FUNCS and next not in YIELD_IGNORE and next[0] == '_']
print
print "Suggested list of yield functions for the emterpreter:"
print " -s EMTERPRETIFY_YIELDLIST='" + str(sorted(list(advised))).replace("'", '"') + "'"
print "(%d%% out of %d functions)" % (int((100.0*len(advised))/len(can_call)), len(can_call))
sys.exit(0)
BLACKLIST = set(list(BLACKLIST) + extra_blacklist)