Author: Armin Rigo <[email protected]>
Branch: stm-thread-2
Changeset: r57286:4dafba14cb5e
Date: 2012-09-11 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/4dafba14cb5e/
Log: in-progress: remove more leftovers, and start to add a test for the
barrier that returns modified objects.
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -617,6 +617,8 @@
assert self.jit_wb_cards_set_singlebyte == -0x80
else:
self.jit_wb_cards_set = 0
+ #
+ self.wb_slowpath = [0, 0, 0, 0]
def repr_of_descr(self):
if self.stmcat is None:
@@ -671,6 +673,12 @@
return False
return self.get_write_barrier_from_array_fn(cpu) != 0
+ def get_wb_slowpath(self, withcards, withfloats):
+ return self.wb_slowpath[withcards + 2 * withfloats]
+
+ def set_wb_slowpath(self, withcards, withfloats, addr):
+ self.wb_slowpath[withcards + 2 * withfloats] = addr
+
class GcLLDescr_framework(GcLLDescription):
DEBUG = False # forced to True by x86/test/test_zrpy_gc.py
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2045,11 +2045,12 @@
FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
funcbox = self.get_funcbox(self.cpu, func_ptr)
- class WriteBarrierDescr(AbstractDescr):
+ class WriteBarrierDescr(WBDescrForTests):
jit_wb_if_flag = 4096
jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
jit_wb_if_flag_singlebyte = 0x10
- def get_write_barrier_fn(self, cpu):
+ def get_write_barrier_fn(self, cpu, returns_modified_object):
+ assert self.returns_modified_object == returns_modified_object
return funcbox.getint()
#
for cond in [False, True]:
@@ -2072,6 +2073,56 @@
else:
assert record == []
+ def test_cond_call_gc_wb_stm_returns_modified_object(self):
+ def func_void(a):
+ record.append(a)
+ return t
+ record = []
+ #
+ S = lltype.GcStruct('S', ('tid', lltype.Signed))
+ FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
+ func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
+ funcbox = self.get_funcbox(self.cpu, func_ptr)
+ class WriteBarrierDescr(WBDescrForTests):
+ returns_modified_object = True
+ jit_wb_if_flag = 4096
+ jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
+ jit_wb_if_flag_singlebyte = 0x10
+ def get_write_barrier_fn(self, cpu, returns_modified_object):
+ assert self.returns_modified_object == returns_modified_object
+ return funcbox.getint()
+ #
+ for cond in [False, True]:
+ value = random.randrange(-sys.maxint, sys.maxint)
+ if cond:
+ value |= 4096
+ else:
+ value &= ~4096
+ s = lltype.malloc(S)
+ s.tid = value
+ sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
+ t = lltype.malloc(S)
+ tgcref = lltype.cast_opaque_ptr(llmemory.GCREF, t)
+ del record[:]
+ p0 = BoxPtr()
+ operations = [
+ ResOperation(rop.COND_CALL_GC_WB, [p0, ConstInt(0)], None,
+ descr=WriteBarrierDescr()),
+ ResOperation(rop.FINISH, [p0], None, descr=BasicFailDescr(1))
+ ]
+ inputargs = [p0]
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(inputargs, operations, looptoken)
+ fail = self.cpu.execute_token(looptoken, sgcref)
+ assert fail.identifier == 1
+ res = self.cpu.get_latest_value_ref(0)
+ if cond:
+ assert record == [s]
+ assert res == tgcref
+ else:
+ assert record == []
+ assert res == sgcref
+
def test_cond_call_gc_wb_array(self):
def func_void(a):
record.append(a)
@@ -2081,12 +2132,13 @@
FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
funcbox = self.get_funcbox(self.cpu, func_ptr)
- class WriteBarrierDescr(AbstractDescr):
+ class WriteBarrierDescr(WBDescrForTests):
jit_wb_if_flag = 4096
jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
jit_wb_if_flag_singlebyte = 0x10
jit_wb_cards_set = 0 # <= without card marking
- def get_write_barrier_fn(self, cpu):
+ def get_write_barrier_fn(self, cpu, returns_modified_object):
+ assert self.returns_modified_object == returns_modified_object
return funcbox.getint()
#
for cond in [False, True]:
@@ -2128,7 +2180,7 @@
FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
funcbox = self.get_funcbox(self.cpu, func_ptr)
- class WriteBarrierDescr(AbstractDescr):
+ class WriteBarrierDescr(WBDescrForTests):
jit_wb_if_flag = 4096
jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
jit_wb_if_flag_singlebyte = 0x10
@@ -3728,3 +3780,13 @@
def alloc_unicode(self, unicode):
py.test.skip("implement me")
+
+class WBDescrForTests(AbstractDescr):
+ returns_modified_object = False
+ wb_slowpath = (0, 0, 0, 0)
+ def get_wb_slowpath(self, c1, c2):
+ return self.wb_slowpath[c1+2*c2]
+ def set_wb_slowpath(self, c1, c2, addr):
+ i = c1+2*c2
+ self.wb_slowpath = (self.wb_slowpath[:i] + (addr,) +
+ self.wb_slowpath[i+1:])
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -83,7 +83,6 @@
self.float_const_abs_addr = 0
self.malloc_slowpath1 = 0
self.malloc_slowpath2 = 0
- self.wb_slowpath = [0, 0, 0, 0]
self.memcpy_addr = 0
self.setup_failure_recovery()
self._debug = False
@@ -112,13 +111,9 @@
self.memcpy_addr = self.cpu.cast_ptr_to_int(support.memcpy_fn)
self._build_failure_recovery(False)
self._build_failure_recovery(True)
- self._build_wb_slowpath(False)
- self._build_wb_slowpath(True)
if self.cpu.supports_floats:
self._build_failure_recovery(False, withfloats=True)
self._build_failure_recovery(True, withfloats=True)
- self._build_wb_slowpath(False, withfloats=True)
- self._build_wb_slowpath(True, withfloats=True)
support.ensure_sse2_floats()
self._build_float_constants()
self._build_propagate_exception_path()
@@ -355,23 +350,14 @@
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.stack_check_slowpath = rawstart
- def _wb_returns_modified_object(self):
- descr = self.cpu.gc_ll_descr.write_barrier_descr
- return descr.returns_modified_object
-
- def _build_wb_slowpath(self, withcards, withfloats=False):
- descr = self.cpu.gc_ll_descr.write_barrier_descr
- if descr is None:
- return
+ def _build_wb_slowpath(self, descr, withcards, withfloats):
if not withcards:
func = descr.get_write_barrier_fn(self.cpu,
descr.returns_modified_object)
else:
- if descr.jit_wb_cards_set == 0:
- return
+ assert descr.jit_wb_cards_set != 0
func = descr.get_write_barrier_from_array_fn(self.cpu)
- if func == 0:
- return
+ assert func != 0
#
# This builds a helper function called from the slow path of
# write barriers. It must save all registers, and optionally
@@ -440,7 +426,7 @@
mc.RET() # and leave the modified object in [ESP+0]
#
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
- self.wb_slowpath[withcards + 2 * withfloats] = rawstart
+ descr.set_wb_slowpath(withcards, withfloats, rawstart)
@staticmethod
@rgc.no_collect
@@ -2478,11 +2464,18 @@
card_marking = True
mask = descr.jit_wb_if_flag_singlebyte | -0x80
#
- loc_base = arglocs[0]
- self.mc.TEST8(addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs),
- imm(mask))
- self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
- jz_location = self.mc.get_relative_pos()
+ # If the 'descr' is for a conditional barrier (common case),
+ # then produce the condition here. The fast-path that does not
+ # require any call is if some bit in the header of the object is
+ # *cleared*.
+ if mask != 0:
+ loc_base = arglocs[0]
+ byteaddr = addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs)
+ self.mc.TEST8(byteaddr, imm(mask))
+ self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
+ jz_location = self.mc.get_relative_pos()
+ else:
+ jz_location = -1
# for cond_call_gc_wb_array, also add another fast path:
# if GCFLAG_CARDS_SET, then we can just set one bit and be done
@@ -2492,25 +2485,26 @@
self.mc.J_il8(rx86.Conditions['S'], 0) # patched later
js_location = self.mc.get_relative_pos()
else:
- js_location = 0
+ js_location = -1
# Write only a CALL to the helper prepared in advance, passing it as
# argument the address of the structure we are writing into
# (the first argument to COND_CALL_GC_WB).
- helper_num = card_marking
if self._regalloc.xrm.reg_bindings:
- helper_num += 2
- if self.wb_slowpath[helper_num] == 0: # tests only
- assert not we_are_translated()
- self.cpu.gc_ll_descr.write_barrier_descr = descr
- self._build_wb_slowpath(card_marking,
- bool(self._regalloc.xrm.reg_bindings))
- assert self.wb_slowpath[helper_num] != 0
+ withfloats = True
+ else:
+ withfloats = False
+ wb_slowpath = descr.get_wb_slowpath(card_marking, withfloats)
+ if wb_slowpath == 0:
+ # must build the barrier's slow path
+ self._build_wb_slowpath(descr, card_marking, withfloats)
+ wb_slowpath = descr.get_wb_slowpath(card_marking, withfloats)
+ assert wb_slowpath != 0
#
self.mc.PUSH(loc_base)
- self.mc.CALL(imm(self.wb_slowpath[helper_num]))
+ self.mc.CALL(imm(wb_slowpath))
- if self._wb_returns_modified_object():
+ if descr.returns_modified_object:
# the value at [ESP] is not popped in this case, but possibly
# updated. We have to use it to update the register at loc_base
assert isinstance(loc_base, RegLoc)
@@ -2570,9 +2564,10 @@
self.mc.overwrite(jns_location-1, chr(offset))
# patch the JZ above
- offset = self.mc.get_relative_pos() - jz_location
- assert 0 < offset <= 127
- self.mc.overwrite(jz_location-1, chr(offset))
+ if jz_location != -1:
+ offset = self.mc.get_relative_pos() - jz_location
+ assert 0 < offset <= 127
+ self.mc.overwrite(jz_location-1, chr(offset))
genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -444,13 +444,8 @@
if self.can_merge_with_next_guard(op, i, operations):
oplist_with_guard[op.getopnum()](self, op, operations[i + 1])
i += 1
- elif not we_are_translated() and op.getopnum() < 0:
- if op.getopnum() == -124:
- self._consider_force_spill(op)
- elif op.getopnum() == -123:
- self._consider_escape(op)
- else:
- assert 0, op
+ elif not we_are_translated() and op.getopnum() == -124:
+ self._consider_force_spill(op)
else:
oplist[op.getopnum()](self, op)
if op.result is not None:
@@ -1358,12 +1353,6 @@
# This operation is used only for testing
self.force_spill_var(op.getarg(0))
- def _consider_escape(self, op):
- # This operation is used only for testing:
- # it checks that op.getarg(0) is currently not in a reg
- loc = self.loc(op.getarg(0))
- assert not isinstance(loc, RegLoc)
-
def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
shape = gcrootmap.get_basic_shape()
for v, val in self.fm.bindings.items():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit