[pypy-svn] r68035 - pypy/trunk/pypy/jit/metainterp
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 30 16:20:33 CEST 2009
Author: arigo
Date: Wed Sep 30 16:20:33 2009
New Revision: 68035
Modified:
pypy/trunk/pypy/jit/metainterp/codewriter.py
pypy/trunk/pypy/jit/metainterp/pyjitpl.py
Log:
Remove the multiple IndirectCallsets and replace them all
with a single, global dictionary.
Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py Wed Sep 30 16:20:33 2009
@@ -42,35 +42,6 @@
dump.dump_bytecode(self, file=file)
print >> file
-class IndirectCallset(history.AbstractValue):
- def __init__(self, codewriter, graphs):
- self.keys = []
- self.values = []
- for graph in graphs:
- fnptr = codewriter.rtyper.getcallable(graph)
- fnaddress = codewriter.cpu.ts.cast_fnptr_to_root(fnptr)
- self.keys.append(fnaddress)
- self.values.append(codewriter.get_jitcode(graph))
- self.dict = None
-
- def bytecode_for_address(self, fnaddress):
- if we_are_translated():
- if self.dict is None:
- # Build the dictionary at run-time. This is needed
- # because the keys are function addresses, so they
- # can change from run to run.
- self.dict = {}
- keys = self.keys
- values = self.values
- for i in range(len(keys)):
- self.dict[keys[i]] = values[i]
- return self.dict[fnaddress]
- else:
- for i in range(len(self.keys)):
- if fnaddress == self.keys[i]:
- return self.values[i]
- raise KeyError(fnaddress)
-
class SwitchDict(history.AbstractValue):
"Get a 'dict' attribute mapping integer values to bytecode positions."
@@ -83,7 +54,6 @@
def __init__(self, metainterp_sd, policy):
self.all_prebuilt_values = dict_equal_consts()
self.all_graphs = {}
- self.all_indirectcallsets = {}
self.all_methdescrs = {}
self.all_listdescs = {}
self.unfinished_graphs = []
@@ -173,14 +143,15 @@
calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), FUNC.RESULT)
return (cfnptr, calldescr)
- def get_indirectcallset(self, graphs):
- key = tuple(sorted(graphs))
- try:
- result = self.all_indirectcallsets[key]
- except KeyError:
- result = self.all_indirectcallsets[key] = \
- IndirectCallset(self, graphs)
- return result
+ def register_indirect_call_targets(self, op):
+ targets = self.policy.graphs_from(op, self.cpu.supports_floats)
+ assert targets is not None
+ for graph in targets:
+ fnptr = self.rtyper.getcallable(graph)
+ fnaddress = self.cpu.ts.cast_fnptr_to_root(fnptr)
+ jitcode = self.get_jitcode(graph)
+ self.metainterp_sd._register_indirect_call_target(fnaddress,
+ jitcode)
def get_methdescr(self, SELFTYPE, methname, attach_jitcodes):
# use the type where the method is actually defined as a key. This way
@@ -1097,13 +1068,9 @@
handle_residual_indirect_call = handle_residual_call
def handle_regular_indirect_call(self, op):
- targets = self.codewriter.policy.graphs_from(op,
- self.codewriter.cpu.supports_floats)
- assert targets is not None
+ self.codewriter.register_indirect_call_targets(op)
self.minimize_variables()
- indirectcallset = self.codewriter.get_indirectcallset(targets)
self.emit('indirect_call')
- self.emit(self.get_position(indirectcallset))
self.emit(self.var_position(op.args[0]))
self.emit_varargs([x for x in op.args[1:-1]
if x.concretetype is not lltype.Void])
Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Wed Sep 30 16:20:33 2009
@@ -73,11 +73,6 @@
args += (bytecode, )
elif argspec == "orgpc":
args += (orgpc, )
- elif argspec == "indirectcallset":
- indirectcallset = self.load_const_arg()
- assert isinstance(indirectcallset,
- codewriter.IndirectCallset)
- args += (indirectcallset, )
elif argspec == "methdescr":
methdescr = self.load_const_arg()
assert isinstance(methdescr,
@@ -660,13 +655,12 @@
def opimpl_residual_call_pure(self, calldescr, varargs):
self.execute_varargs(rop.CALL_PURE, varargs, descr=calldescr, exc=False)
-
- @arguments("orgpc", "indirectcallset", "box", "varargs")
- def opimpl_indirect_call(self, pc, indirectcallset, box, varargs):
+ @arguments("orgpc", "box", "varargs")
+ def opimpl_indirect_call(self, pc, box, varargs):
box = self.implement_guard_value(pc, box)
cpu = self.metainterp.cpu
key = cpu.ts.getaddr_for_box(cpu, box)
- jitcode = indirectcallset.bytecode_for_address(key)
+ jitcode = self.metainterp.staticdata.bytecode_for_address(key)
f = self.metainterp.newframe(jitcode)
f.setup_call(varargs)
return True
@@ -972,6 +966,9 @@
self.opcode_names = []
self.opname_to_index = {}
+ self.indirectcall_keys = []
+ self.indirectcall_values = []
+
self.warmrunnerdesc = warmrunnerdesc
self._op_goto_if_not = self.find_opcode('goto_if_not')
@@ -1023,6 +1020,26 @@
self.portal_graph)
self._class_sizes = self._codewriter.class_sizes
+ def bytecode_for_address(self, fnaddress):
+ if we_are_translated():
+ d = self.globaldata.indirectcall_dict
+ if d is None:
+ # Build the dictionary at run-time. This is needed
+ # because the keys are function addresses, so they
+ # can change from run to run.
+ d = {}
+ keys = self.indirectcall_keys
+ values = self.indirectcall_values
+ for i in range(len(keys)):
+ d[keys[i]] = values[i]
+ self.globaldata.indirectcall_dict = d
+ return d[fnaddress]
+ else:
+ for i in range(len(self.indirectcall_keys)):
+ if fnaddress == self.indirectcall_keys[i]:
+ return self.indirectcall_values[i]
+ raise KeyError(fnaddress)
+
# ---------- construction-time interface ----------
def _register_opcode(self, opname):
@@ -1033,6 +1050,10 @@
self.opcode_names.append(opname)
self.opcode_implementations.append(getattr(MIFrame, name).im_func)
+ def _register_indirect_call_target(self, fnaddress, jitcode):
+ self.indirectcall_keys.append(fnaddress)
+ self.indirectcall_values.append(jitcode)
+
def find_opcode(self, name):
try:
return self.opname_to_index[name]
@@ -1054,6 +1075,7 @@
class MetaInterpGlobalData(object):
def __init__(self, staticdata):
self.initialized = False
+ self.indirectcall_dict = None
#
state = staticdata.state
if state is not None:
More information about the Pypy-commit
mailing list