-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjitcode.py
More file actions
154 lines (131 loc) · 5.47 KB
/
Copy pathjitcode.py
File metadata and controls
154 lines (131 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from rpython.jit.metainterp.history import AbstractDescr, ConstInt
from rpython.jit.metainterp.support import adr2int
from rpython.rlib.objectmodel import we_are_translated, specialize
from rpython.rlib.rarithmetic import base_int
class JitCode(AbstractDescr):
_empty_i = []
_empty_r = []
_empty_f = []
def __init__(self, name, fnaddr=None, calldescr=None, called_from=None):
self.name = name
self.fnaddr = fnaddr
self.calldescr = calldescr
self.jitdriver_sd = None # None for non-portals
self._called_from = called_from # debugging
self._ssarepr = None # debugging
def setup(self, code='', constants_i=[], constants_r=[], constants_f=[],
num_regs_i=255, num_regs_r=255, num_regs_f=255,
startpoints=None, alllabels=None,
resulttypes=None):
self.code = code
for x in constants_i:
assert not isinstance(x, base_int), (
"found constant %r of type %r, must not appear in "
"JitCode.constants_i" % (x, type(x)))
# if the following lists are empty, use a single shared empty list
self.constants_i = constants_i or self._empty_i
self.constants_r = constants_r or self._empty_r
self.constants_f = constants_f or self._empty_f
# encode the three num_regs into a single char each
assert num_regs_i < 256 and num_regs_r < 256 and num_regs_f < 256
self.c_num_regs_i = chr(num_regs_i)
self.c_num_regs_r = chr(num_regs_r)
self.c_num_regs_f = chr(num_regs_f)
self._startpoints = startpoints # debugging
self._alllabels = alllabels # debugging
self._resulttypes = resulttypes # debugging
def get_fnaddr_as_int(self):
return adr2int(self.fnaddr)
def num_regs_i(self):
return ord(self.c_num_regs_i)
def num_regs_r(self):
return ord(self.c_num_regs_r)
def num_regs_f(self):
return ord(self.c_num_regs_f)
def _live_vars(self, pc, all_liveness, op_live):
from rpython.jit.codewriter.liveness import LivenessIterator
# for testing only
if ord(self.code[pc]) != op_live:
self._missing_liveness(pc)
offset = self.get_live_vars_info(pc, op_live)
lst_i = []
lst_r = []
lst_f = []
enumerate_vars(offset, all_liveness,
lambda index: lst_i.append("%%i%d" % (index, )),
lambda index: lst_r.append("%%r%d" % (index, )),
lambda index: lst_f.append("%%f%d" % (index, )),
None)
return ' '.join(lst_i + lst_r + lst_f)
def get_live_vars_info(self, pc, op_live):
from rpython.jit.codewriter.liveness import decode_offset, OFFSET_SIZE
# either this, or the previous instruction must be -live-
if not we_are_translated():
assert pc in self._startpoints
if ord(self.code[pc]) != op_live:
pc -= OFFSET_SIZE + 1
if not we_are_translated():
assert pc in self._startpoints
if ord(self.code[pc]) != op_live:
self._missing_liveness(pc)
return decode_offset(self.code, pc + 1)
def _missing_liveness(self, pc):
msg = "missing liveness[%d] in %s" % (pc, self.name)
if we_are_translated():
print msg
raise AssertionError
raise MissingLiveness("%s\n%s" % (msg, self.dump()))
def follow_jump(self, position):
"""Assuming that 'position' points just after a bytecode
instruction that ends with a label, follow that label."""
code = self.code
position -= 2
assert position >= 0
if not we_are_translated():
assert position in self._alllabels
labelvalue = ord(code[position]) | (ord(code[position+1])<<8)
assert labelvalue < len(code)
return labelvalue
def dump(self):
if self._ssarepr is None:
return '<no dump available for %r>' % (self.name,)
else:
from rpython.jit.codewriter.format import format_assembler
return format_assembler(self._ssarepr)
def __repr__(self):
return '<JitCode %r>' % self.name
def _clone_if_mutable(self):
raise NotImplementedError
class MissingLiveness(Exception):
pass
class SwitchDictDescr(AbstractDescr):
"Get a 'dict' attribute mapping integer values to bytecode positions."
def attach(self, as_dict):
self.dict = as_dict
self.const_keys_in_order = map(ConstInt, sorted(as_dict.keys()))
def __repr__(self):
dict = getattr(self, 'dict', '?')
return '<SwitchDictDescr %s>' % (dict,)
def _clone_if_mutable(self):
raise NotImplementedError
@specialize.arg(5)
def enumerate_vars(offset, all_liveness, callback_i, callback_r, callback_f, spec):
from rpython.jit.codewriter.liveness import LivenessIterator
length_i = ord(all_liveness[offset])
length_r = ord(all_liveness[offset + 1])
length_f = ord(all_liveness[offset + 2])
offset += 3
if length_i:
it = LivenessIterator(offset, length_i, all_liveness)
for index in it:
callback_i(index)
offset = it.offset
if length_r:
it = LivenessIterator(offset, length_r, all_liveness)
for index in it:
callback_r(index)
offset = it.offset
if length_f:
it = LivenessIterator(offset, length_f, all_liveness)
for index in it:
callback_f(index)