[pypy-svn] r70956 - in pypy/branch/gc-huge-list/pypy/jit/backend: test x86 x86/test
arigo at codespeak.net
arigo at codespeak.net
Thu Jan 28 18:07:55 CET 2010
Author: arigo
Date: Thu Jan 28 18:07:54 2010
New Revision: 70956
Modified:
pypy/branch/gc-huge-list/pypy/jit/backend/test/runner_test.py
pypy/branch/gc-huge-list/pypy/jit/backend/x86/assembler.py
pypy/branch/gc-huge-list/pypy/jit/backend/x86/regalloc.py
pypy/branch/gc-huge-list/pypy/jit/backend/x86/test/test_gc_integration.py
Log:
(arigo, fijal)
Implement the new write barrier for JIT's x86 backend.
Modified: pypy/branch/gc-huge-list/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/jit/backend/test/runner_test.py (original)
+++ pypy/branch/gc-huge-list/pypy/jit/backend/test/runner_test.py Thu Jan 28 18:07:54 2010
@@ -1261,14 +1261,17 @@
self.cpu.clear_exception()
def test_cond_call_gc_wb(self):
- def func_void(a, b):
- record.append((a, b))
+ def func_void(a, b, c):
+ record.append((a, b, c))
record = []
#
- FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Void)
+ FUNC = self.FuncType([lltype.Signed, lltype.Signed, lltype.Signed],
+ lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
funcbox = self.get_funcbox(self.cpu, func_ptr)
calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ T = lltype.GcStruct('T', ('name', lltype.Signed))
+ fielddescr = self.cpu.fielddescrof(T, 'name')
for cond in [False, True]:
value = random.randrange(-sys.maxint, sys.maxint)
if cond:
@@ -1278,10 +1281,42 @@
del record[:]
self.execute_operation(rop.COND_CALL_GC_WB,
[BoxInt(value), ConstInt(4096),
- funcbox, BoxInt(655360), BoxInt(-2121)],
+ funcbox, BoxInt(655360), BoxInt(-2121),
+ fielddescr],
+ 'void', descr=calldescr)
+ if cond:
+ assert record == [(655360, -2121, fielddescr.offset)]
+ else:
+ assert record == []
+
+ def test_cond_call_gc_wb_array(self):
+ def func_void(a, b, c):
+ record.append((a, b, c))
+ record = []
+ #
+ FUNC = self.FuncType([lltype.Signed, lltype.Signed, lltype.Signed],
+ lltype.Void)
+ func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
+ funcbox = self.get_funcbox(self.cpu, func_ptr)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ A = lltype.GcArray(lltype.Signed)
+ arraydescr = self.cpu.arraydescrof(A)
+ for cond in [False, True]:
+ value = random.randrange(-sys.maxint, sys.maxint)
+ if cond:
+ value |= 4096
+ else:
+ value &= ~4096
+ del record[:]
+ self.execute_operation(rop.COND_CALL_GC_WB_ARRAY,
+ [BoxInt(value), ConstInt(4096),
+ funcbox, BoxInt(655360), BoxInt(-2121),
+ arraydescr, BoxInt(3)],
'void', descr=calldescr)
if cond:
- assert record == [(655360, -2121)]
+ offset = arraydescr.get_base_size(False)
+ size = arraydescr.get_item_size(False)
+ assert record == [(655360, -2121, offset + size * 3)]
else:
assert record == []
Modified: pypy/branch/gc-huge-list/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/gc-huge-list/pypy/jit/backend/x86/assembler.py Thu Jan 28 18:07:54 2010
@@ -413,7 +413,10 @@
resloc, current_depths)
def load_effective_addr(self, sizereg, baseofs, scale, result):
- self.mc.LEA(result, addr_add(imm(0), sizereg, baseofs, scale))
+ self.mc.LEA(result, self.effective_addr(sizereg, baseofs, scale))
+
+ def effective_addr(self, sizereg, baseofs, scale):
+ return addr_add(imm(0), sizereg, baseofs, scale)
def _unaryop(asmop):
def genop_unary(self, op, arglocs, resloc):
@@ -1307,6 +1310,12 @@
return self.implement_guard(addr, self.mc.JL)
def genop_discard_cond_call_gc_wb(self, op, arglocs):
+ self._cond_call_gc_wb(op, arglocs, False)
+
+ def genop_discard_cond_call_gc_wb_array(self, op, arglocs):
+ self._cond_call_gc_wb(op, arglocs, True)
+
+ def _cond_call_gc_wb(self, op, arglocs, is_array):
# use 'mc._mc' directly instead of 'mc', to avoid
# bad surprizes if the code buffer is mostly full
loc_cond = arglocs[0]
@@ -1317,8 +1326,29 @@
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, 2, -1):
+ # At this point, arglocs is:
+ # [cond, mask, fn, arg1, arg2, arg3, regs_to_save_and_restore....]
+ # except that arg3 needs to be replaced by "LEA reg, arg3" if is_array.
+ # First push regs_to_save_and_restore
+ for i in range(len(arglocs)-1, 5, -1):
mc.PUSH(arglocs[i])
+ # Push arg3 or the result of "LEA reg, arg3"
+ if not is_array:
+ mc.PUSH(arglocs[5])
+ else:
+ # We need a free register in (eax, ecx, edx)
+ # which is not arglocs[3] or arglocs[4]
+ tmpreg = eax
+ if tmpreg is arglocs[3] or tmpreg is arglocs[4]:
+ tmpreg = ecx
+ if tmpreg is arglocs[3] or tmpreg is arglocs[4]:
+ tmpreg = edx
+ mc.LEA(tmpreg, arglocs[5])
+ mc.PUSH(tmpreg)
+ # Push arg2 and arg1
+ mc.PUSH(arglocs[4])
+ mc.PUSH(arglocs[3])
+ # Done pushing arguments...
mc.CALL(rel32(op.args[2].getint()))
pop_count = 0
for i in range(3, len(arglocs)):
Modified: pypy/branch/gc-huge-list/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/gc-huge-list/pypy/jit/backend/x86/regalloc.py Thu Jan 28 18:07:54 2010
@@ -655,7 +655,15 @@
def consider_cond_call_gc_wb(self, op):
assert op.result is None
- arglocs = [self.loc(arg) for arg in op.args]
+ arglocs = []
+ for i in range(len(op.args) - 1):
+ arglocs.append(self.loc(op.args[i]))
+ descr = op.args[-1]
+ ofsloc = self._unpack_fielddescr(descr)[0]
+ arglocs.append(ofsloc)
+ self._call_wb_common(op, arglocs, 1)
+
+ def _call_wb_common(self, op, arglocs, toignore):
# add eax, ecx and edx as extra "arguments" to ensure they are
# saved and restored. Fish in self.rm to know which of these
# registers really need to be saved (a bit of a hack). Moreover,
@@ -668,7 +676,21 @@
and reg not in arglocs[3:]):
arglocs.append(reg)
self.PerformDiscard(op, arglocs)
- self.rm.possibly_free_vars(op.args)
+ for i in range(len(op.args) - toignore):
+ self.rm.possibly_free_var(op.args[i])
+
+ def consider_cond_call_gc_wb_array(self, op):
+ assert op.result is None
+ arglocs = []
+ index = op.args[-1]
+ index_loc = self.make_sure_var_in_reg(index)
+ for i in range(len(op.args) - 2):
+ arglocs.append(self.loc(op.args[i]))
+ descr = op.args[-2]
+ scale, ofs, ptr = self._unpack_arraydescr(descr)
+ arglocs.append(self.assembler.effective_addr(index_loc, ofs, scale))
+ self._call_wb_common(op, arglocs, 2)
+ self.rm.possibly_free_var(index)
def _fastpath_malloc(self, op, descr):
assert isinstance(descr, BaseSizeDescr)
Modified: pypy/branch/gc-huge-list/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/jit/backend/x86/test/test_gc_integration.py (original)
+++ pypy/branch/gc-huge-list/pypy/jit/backend/x86/test/test_gc_integration.py Thu Jan 28 18:07:54 2010
@@ -285,3 +285,5 @@
assert gc_ll_descr.nursery[1] == self.vtable_int
nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
assert gc_ll_descr.addrs[0] == nurs_adr + 8
+
+
More information about the Pypy-commit
mailing list