[pypy-svn] r67356 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86
arigo at codespeak.net
arigo at codespeak.net
Mon Aug 31 14:28:29 CEST 2009
Author: arigo
Date: Mon Aug 31 14:28:28 2009
New Revision: 67356
Modified:
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py
Log:
Fix the x86 backend.
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py Mon Aug 31 14:28:28 2009
@@ -142,14 +142,6 @@
ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
ll_new_unicode)
- # for moving GCs, the array used to hold the address of GC objects
- # that appear as ConstPtr.
- if gc_ll_descr.moving_gc:
- from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
- self.gcrefs = gc_ll_descr.GcRefList()
- self.single_gcref_descr = GcPtrFieldDescr(0)
- else:
- self.gcrefs = None
self.gcrootmap = gc_ll_descr.gcrootmap
if self.gcrootmap:
self.gcrootmap.initialize()
@@ -569,6 +561,7 @@
assert 0, itemsize
genop_discard_setfield_raw = genop_discard_setfield_gc
+ genop_discard_setarrayitem_raw = genop_discard_setarrayitem_gc
def genop_strlen(self, op, arglocs, resloc):
base_loc = arglocs[0]
@@ -583,9 +576,9 @@
self.mc.MOV(resloc, addr_add_const(base_loc, ofs_length))
def genop_arraylen_gc(self, op, arglocs, resloc):
- ofs = self.cpu.gc_ll_descr.array_length_ofs
base_loc, ofs_loc = arglocs
- self.mc.MOV(resloc, addr_add_const(base_loc, ofs))
+ assert isinstance(ofs_loc, IMM32)
+ self.mc.MOV(resloc, addr_add_const(base_loc, ofs_loc.value))
def genop_strgetitem(self, op, arglocs, resloc):
base_loc, ofs_loc = arglocs
@@ -773,42 +766,34 @@
genop_call_pure = genop_call
- def genop_cond_call(self, op, arglocs, resloc):
- sizeloc = arglocs[0]
- assert isinstance(sizeloc, IMM32)
- size = sizeloc.value
+ def genop_discard_cond_call_gc_wb(self, op, arglocs):
# use 'mc._mc' directly instead of 'mc', to avoid
# bad surprizes if the code buffer is mostly full
- loc_cond = arglocs[1]
- loc_mask = arglocs[2]
- loc_value_if_false = arglocs[3]
+ loc_cond = arglocs[0]
+ loc_mask = arglocs[1]
mc = self.mc._mc
mc.TEST(loc_cond, loc_mask)
mc.write('\x74\x00') # JZ after_the_call
jz_location = mc.get_relative_pos()
# the following is supposed to be the slow path, so whenever possible
# we choose the most compact encoding over the most efficient one.
- for i in range(len(arglocs)-1, 4, -1):
+ for i in range(len(arglocs)-1, 2, -1):
mc.PUSH(arglocs[i])
- mc.CALL(rel32(op.args[3].getint()))
- if size == 1:
- mc.MOVZX(resloc, al)
- elif size == 2:
- mc.MOVZX(resloc, eax) # actually reads the AX part only
- elif resloc is not None and resloc is not eax:
- mc.XCHG(eax, resloc)
+ mc.CALL(rel32(op.args[2].getint()))
pop_count = 0
- for i in range(5, len(arglocs)):
+ for i in range(3, len(arglocs)):
loc = arglocs[i]
pop_count += 1
- if loc is not resloc and isinstance(loc, REG):
+ if isinstance(loc, REG):
while pop_count > 0:
mc.POP(loc)
pop_count -= 1
if pop_count:
mc.ADD(esp, imm(WORD * pop_count))
# patch the JZ above
- mc.overwrite(jz_location-1, chr(mc.get_relative_pos() - jz_location))
+ offset = mc.get_relative_pos() - jz_location
+ assert 0 < offset <= 127
+ mc.overwrite(jz_location-1, chr(offset))
def not_implemented_op_discard(self, op, arglocs):
print "not implemented operation: %s" % op.getopname()
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py Mon Aug 31 14:28:28 2009
@@ -59,7 +59,8 @@
self.assembler = assembler
self.translate_support_code = translate_support_code
if regalloc is None:
- self._rewrite_const_ptrs(tree.operations)
+ gc_ll_descr = self.assembler.cpu.gc_ll_descr
+ gc_ll_descr.rewrite_assembler(self, tree.operations)
self.tree = tree
self.reg_bindings = newcheckdict()
self.stack_bindings = newcheckdict()
@@ -215,38 +216,6 @@
self.max_stack_depth = max(self.max_stack_depth,
self.current_stack_depth + 1)
- def _rewrite_const_ptrs(self, operations):
- # Idea: when running on a moving GC, we can't (easily) encode
- # the ConstPtrs in the assembler, because they can move at any
- # point in time. Instead, we store them in 'gcrefs.list', a GC
- # but nonmovable list; and here, we modify 'operations' to
- # replace direct usage of ConstPtr with a BoxPtr loaded by a
- # GETFIELD_RAW from the array 'gcrefs.list'.
- gcrefs = self.assembler.gcrefs
- if gcrefs is None:
- return
- single_gcref_descr = self.assembler.single_gcref_descr
- newops = []
- for op in operations:
- if op.opnum == rop.DEBUG_MERGE_POINT:
- continue
- for i in range(len(op.args)):
- v = op.args[i]
- if (isinstance(v, ConstPtr) and v.value
- and rgc.can_move(v.value)):
- box = BoxPtr(v.value)
- addr = gcrefs.get_address_of_gcref(v.value)
- addr = rffi.cast(lltype.Signed, addr)
- newops.append(ResOperation(rop.GETFIELD_RAW,
- [ConstInt(addr)], box,
- single_gcref_descr))
- op.args[i] = box
- if op.is_guard():
- self._rewrite_const_ptrs(op.suboperations)
- newops.append(op)
- del operations[:]
- operations.extend(newops)
-
def _compute_vars_longevity(self, inputargs, operations):
# compute a dictionary that maps variables to index in
# operations that is a "last-time-seen"
@@ -725,31 +694,18 @@
consider_call_pure = consider_call
- def consider_cond_call(self, op, ignored):
- calldescr = op.descr
- assert isinstance(calldescr, BaseCallDescr)
- v_cond = op.args[0]
- v_mask = op.args[1]
- v_value_if_false = op.args[2]
- if op.result is not None:
- resloc = self.force_result_in_reg(op.result, v_value_if_false, [])
- else:
- resloc = None
- condloc = self.loc(v_cond)
- arglocs = [resloc] + [self.loc(arg) for arg in op.args[3:]]
+ def consider_cond_call_gc_wb(self, op, ignored):
+ assert op.result is None
+ arglocs = [self.loc(arg) for arg in op.args]
# add eax, ecx and edx as extra "arguments" to ensure they are
- # saved and restored. Don't add them if they are equal to resloc!
+ # saved and restored.
for v, reg in self.reg_bindings.items():
if ((reg is eax or reg is ecx or reg is edx)
and self.longevity[v][1] > self.position
- and reg not in arglocs):
+ and reg not in arglocs[3:]):
arglocs.append(reg)
- size = calldescr.get_result_size(self.translate_support_code)
- self.Perform(op,
- [imm(size), condloc, convert_to_imm(v_mask)] + arglocs,
- resloc)
- self.eventually_free_var(v_cond)
- self.eventually_free_vars(op.args[3:])
+ self.PerformDiscard(op, arglocs)
+ self.eventually_free_vars(op.args)
def consider_new(self, op, ignored):
args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr)
@@ -841,7 +797,7 @@
ptr = fielddescr.is_pointer_field()
return imm(ofs), imm(size), ptr
- def _common_consider_setfield(self, op, ignored, raw):
+ def consider_setfield_gc(self, op, ignored):
ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr)
assert isinstance(size_loc, IMM32)
if size_loc.value == 1:
@@ -851,20 +807,10 @@
base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
value_loc = self.make_sure_var_in_reg(op.args[1], op.args,
need_lower_byte=need_lower_byte)
- if ptr:
- if raw:
- print "Setfield of raw structure with gc pointer"
- assert False
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
- gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc)
self.eventually_free_vars(op.args)
self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc])
- def consider_setfield_gc(self, op, ignored):
- self._common_consider_setfield(op, ignored, raw=False)
-
- def consider_setfield_raw(self, op, ignored):
- self._common_consider_setfield(op, ignored, raw=True)
+ consider_setfield_raw = consider_setfield_gc
def consider_strsetitem(self, op, ignored):
base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
@@ -886,13 +832,12 @@
value_loc = self.make_sure_var_in_reg(op.args[2], op.args,
need_lower_byte=need_lower_byte)
ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
- if ptr:
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
- gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc)
self.eventually_free_vars(op.args)
self.PerformDiscard(op, [base_loc, ofs_loc, value_loc,
imm(scale), imm(ofs)])
+ consider_setarrayitem_raw = consider_setarrayitem_gc
+
def consider_getfield_gc(self, op, ignored):
ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr)
base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
@@ -952,7 +897,9 @@
consider_unicodelen = consider_strlen
def consider_arraylen_gc(self, op, ignored):
- _, ofs, _ = self._unpack_arraydescr(op.descr)
+ arraydescr = op.descr
+ assert isinstance(arraydescr, BaseArrayDescr)
+ ofs = arraydescr.get_ofs_length(self.translate_support_code)
base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
self.eventually_free_vars(op.args)
result_loc = self.force_allocate_reg(op.result, [])
More information about the Pypy-commit
mailing list