Permalink
Browse files

More work on opcode comparison.

- diff histograms of OPy vs. CPython
- clean up the disassemble function in misc/inspect_pyc.py.
  • Loading branch information...
Andy Chu
Andy Chu committed Mar 13, 2018
1 parent 4c29ee0 commit 0b0f2e1008ef0a80db5e5838a0ffb7b343078236
Showing with 63 additions and 27 deletions.
  1. +26 −6 opy/count.sh
  2. +30 −20 opy/misc/inspect_pyc.py
  3. +7 −1 opy/opy_main.py
View
@@ -50,13 +50,33 @@ all() {
# With opy: 39, 38, 35, 24. Oh so there's 1 more or one less. Interesting!
# TODO: diff them.
# differences:
# PRINT_ITEM, PRINT_NEWLINE
# UNARY_NEGATIVE
# UNARY_NOT: big differences in magnitudes! Is this a bug?
readonly PARSER=(osh/{cmd,bool,word,arith}_parse.pyc)
opcodes-comparison() {
for pyc in "${PARSER[@]}"; do
echo
echo "=== $pyc ==="
echo
bin/opyc dis $pyc cpython.txt >/dev/null
bin/opyc dis _tmp/oil-with-opy/$pyc opy.txt >/dev/null
local diff=${DIFF:-diff -u}
$diff {cpython,opy}.txt
done
}
opcodes() {
for prefix in '' _tmp/oil-with-opy/; do
for pyc in \
${prefix}osh/{cmd,bool,word,arith}_parse.pyc; do
echo $pyc
bin/opyc dis $pyc | tail -n 1
done
for pyc in "${PARSER[@]}"; do
echo
echo "=== $pyc ==="
echo
bin/opyc dis _tmp/oil-with-opy/$pyc
done
}
View
@@ -120,16 +120,14 @@ def out(*args, **kwargs):
prefix = linestarts[i]
else:
prefix = ''
out('%s%3s' % (indent, prefix), end=' ')
out('%s%4s' % (indent, prefix), end=' ')
out(' ', end=' ')
if i in labels: # Jump targets get a special symbol
out('>>', end=' ')
arrow = '>>'
else:
out(' ', end=' ')
arrow = ' '
out(repr(i).rjust(4), end=' ')
out(dis.opname[op].ljust(20), end=' ')
out(' %s %4r %-20s ' % (arrow, i, dis.opname[op]), end=' ')
i += 1
if op >= dis.HAVE_ARGUMENT:
oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
@@ -138,21 +136,33 @@ def out(*args, **kwargs):
if op == dis.EXTENDED_ARG:
extended_arg = oparg*65536L
out(repr(oparg).rjust(5), end=' ')
oparg_str = None
if op in dis.hasconst:
out('(' + repr(co.co_consts[oparg]) + ')', end=' ')
oparg_str = '(%r)' % (co.co_consts[oparg],)
elif op in dis.hasname:
out('(' + co.co_names[oparg] + ')', end=' ')
oparg_str = '(%s)' % (co.co_names[oparg],)
elif op in dis.hasjrel:
out('(to ' + repr(i + oparg) + ')', end=' ')
oparg_str = '(to %r)' % (i + oparg,)
elif op in dis.haslocal:
out('(' + co.co_varnames[oparg] + ')', end=' ')
oparg_str = '(%s)' % (co.co_varnames[oparg],)
elif op in dis.hascompare:
out('(' + dis.cmp_op[oparg] + ')', end=' ')
oparg_str = '(%s)' % (dis.cmp_op[oparg],)
elif op in dis.hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
out('(' + free[oparg] + ')', end=' ')
if free is None:
free = co.co_cellvars + co.co_freevars
oparg_str = '(%s)' % (free[oparg],)
if oparg_str:
out('%5r %s' % (oparg, oparg_str), end=' ')
else:
out('%5r' % oparg, end=' ')
out()
@@ -222,11 +232,11 @@ def Visit(self, f):
self.show_code(code, level=1)
print(" ## done inspecting pyc file ##")
def Report(self):
def Report(self, f=sys.stdout):
print()
print('Opcode Histogram:')
print('Opcode Histogram:', file=f)
for op, count in self.op_counts.most_common():
print('%5d %s' % (count, dis.opname[op]))
print('%5d %s' % (count, dis.opname[op]), file=f)
print()
print('%d unique opcodes' % len(self.op_counts))
print('', file=f)
print('%d unique opcodes' % len(self.op_counts), file=f)
View
@@ -264,13 +264,19 @@ def py2st(gr, raw_node):
elif action == 'dis':
pyc_path = argv[1]
try:
report_path = argv[2]
report_f = open(report_path, 'w')
except IndexError:
report_f = sys.stdout
with open(pyc_path, 'rb') as f:
# TODO: Make this a flag.
#v = inspect_pyc.Visitor(dis_bytecode=False)
v = inspect_pyc.Visitor()
v.Visit(f)
v.Report()
v.Report(report_f)
# NOTE: Unused
elif action == 'old-compile':

0 comments on commit 0b0f2e1

Please sign in to comment.