Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r70159:f7dc1aca6874
Date: 2014-03-22 11:43 +0100
http://bitbucket.org/pypy/pypy/changeset/f7dc1aca6874/
Log: Revert some more changes
diff --git a/rpython/jit/backend/llsupport/gc.py
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -280,60 +280,16 @@
def get_root_stack_top_addr(self):
rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address)
return rffi.cast(lltype.Signed, rst_addr)
-
-
-class BarrierDescr(AbstractDescr):
+
+class WriteBarrierDescr(AbstractDescr):
def __init__(self, gc_ll_descr):
self.llop1 = gc_ll_descr.llop1
-
- self.returns_modified_object = False
- self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
- self.HDRPTR = gc_ll_descr.HDRPTR
- self.b_slowpath = [0, 0, 0, 0, 0]
-
- def repr_of_descr(self):
- raise NotImplementedError
-
- def __repr(self):
- raise NotImplementedError
-
- def get_b_slowpath(self, num):
- return self.b_slowpath[num]
-
- def set_b_slowpath(self, num, addr):
- self.b_slowpath[num] = addr
-
- def get_barrier_funcptr(self, returns_modified_object):
- raise NotImplementedError
-
- def get_barrier_fn(self, cpu, returns_modified_object):
- # must pass in 'self.returns_modified_object', to make sure that
- # the callers are fixed for this case
- funcptr = self.get_barrier_funcptr(returns_modified_object)
- funcaddr = llmemory.cast_ptr_to_adr(funcptr)
- return cpu.cast_adr_to_int(funcaddr)
-
- def get_barrier_from_array_fn(self, cpu):
- # returns a function with arguments [array, index, newvalue]
- llop1 = self.llop1
- funcptr = llop1.get_write_barrier_from_array_failing_case(
- self.FUNCPTR)
- funcaddr = llmemory.cast_ptr_to_adr(funcptr)
- return cpu.cast_adr_to_int(funcaddr) # this may return 0
-
- def has_barrier_from_array(self, cpu):
- return self.get_barrier_from_array_fn(cpu) != 0
-
-
-
-class WriteBarrierDescr(BarrierDescr):
- def __init__(self, gc_ll_descr):
- BarrierDescr.__init__(self, gc_ll_descr)
+ self.WB_FUNCPTR = gc_ll_descr.WB_FUNCPTR
self.fielddescr_tid = gc_ll_descr.fielddescr_tid
- self.FUNCPTR = lltype.Ptr(lltype.FuncType(
- [llmemory.Address], lltype.Void))
-
+ #
GCClass = gc_ll_descr.GCClass
+ if GCClass is None: # for tests
+ return
self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
self.jit_wb_if_flag_byteofs, self.jit_wb_if_flag_singlebyte = (
self.extract_flag_byte(self.jit_wb_if_flag))
@@ -351,17 +307,9 @@
else:
self.jit_wb_cards_set = 0
- def repr_of_descr(self):
- return 'wbdescr'
-
- def __repr__(self):
- return '<WriteBarrierDescr %r>' % (self.repr_of_descr(),)
-
def extract_flag_byte(self, flag_word):
# if convenient for the backend, we compute the info about
# the flag as (byte-offset, single-byte-flag).
- if flag_word == 0:
- return (0, 0)
import struct
value = struct.pack(lltype.SignedFmt, flag_word)
assert value.count('\x00') == len(value) - 1 # only one byte is != 0
@@ -369,143 +317,24 @@
while value[i] == '\x00': i += 1
return (i, struct.unpack('b', value[i])[0])
- def get_barrier_funcptr(self, returns_modified_object):
- assert not returns_modified_object
- FUNCTYPE = self.FUNCPTR
- return self.llop1.get_write_barrier_failing_case(FUNCTYPE)
+ def get_write_barrier_fn(self, cpu):
+ llop1 = self.llop1
+ funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
+ funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+ return cpu.cast_adr_to_int(funcaddr)
- @specialize.arg(2)
- def _do_barrier(self, gcref_struct, returns_modified_object):
- assert self.returns_modified_object == returns_modified_object
- hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct)
- hdr_addr -= self.gcheaderbuilder.size_gc_header
- hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR)
- if self.jit_wb_if_flag == 0 or hdr.tid & self.jit_wb_if_flag:
- # get a pointer to the 'remember_young_pointer' function from
- # the GC, and call it immediately
- funcptr = self.get_barrier_funcptr(returns_modified_object)
- funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
+ def get_write_barrier_from_array_fn(self, cpu):
+ # returns a function with arguments [array, index, newvalue]
+ llop1 = self.llop1
+ funcptr = llop1.get_write_barrier_from_array_failing_case(
+ self.WB_FUNCPTR)
+ funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+ return cpu.cast_adr_to_int(funcaddr) # this may return 0
-
-class STMBarrierDescr(BarrierDescr):
- def __init__(self, gc_ll_descr, stmcat, cfunc_name):
- BarrierDescr.__init__(self, gc_ll_descr)
- self.stmcat = stmcat
- self.returns_modified_object = True
- self.B_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
- [llmemory.Address], llmemory.Address))
+ def has_write_barrier_from_array(self, cpu):
+ return self.get_write_barrier_from_array_fn(cpu) != 0
- self.b_failing_case_ptr = rffi.llexternal(
- cfunc_name,
- self.B_FUNCPTR_MOD.TO.ARGS,
- self.B_FUNCPTR_MOD.TO.RESULT,
- sandboxsafe=True,
- _nowrapper=True)
- def repr_of_descr(self):
- return self.stmcat
-
- def __repr__(self):
- return '<STMBarrierDescr %r>' % (self.repr_of_descr(),)
-
- def get_barrier_funcptr(self, returns_modified_object):
- assert returns_modified_object
- return self.b_failing_case_ptr
-
- @specialize.arg(2)
- def _do_barrier(self, gcref_struct, returns_modified_object):
- raise NotImplementedError("implement in subclasses!")
- assert self.returns_modified_object == returns_modified_object
- funcptr = self.get_barrier_funcptr(returns_modified_object)
- res = funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
- return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
-
-
-class STMReadBarrierDescr(STMBarrierDescr):
- def __init__(self, gc_ll_descr, stmcat):
- assert stmcat in ['A2R', 'Q2R', 'A2I']
- func = {'A2R': 'stm_DirectReadBarrier',
- 'Q2R': 'stm_RepeatReadBarrier',
- 'A2I': 'stm_ImmutReadBarrier',
- }
-
- STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- func[stmcat])
-
- @specialize.arg(2)
- def _do_barrier(self, gcref_struct, returns_modified_object):
- assert returns_modified_object
- from rpython.memory.gc.stmgc import StmGC
- objadr = llmemory.cast_ptr_to_adr(gcref_struct)
- objhdr = rffi.cast(StmGC.GCHDRP, gcref_struct)
-
- if self.stmcat == 'A2R':
- # if h_revision == privat_rev of transaction
- priv_rev = self.llop1.stm_get_adr_of_private_rev_num(rffi.SIGNEDP)
- if objhdr.h_revision == priv_rev[0]:
- return gcref_struct
-
- # readcache[obj] == obj
- read_cache =
self.llop1.stm_get_adr_of_read_barrier_cache(rffi.SIGNEDP)
- objint = llmemory.cast_adr_to_int(objadr)
- assert WORD == 8, "check for 32bit compatibility"
- index = (objint & StmGC.FX_MASK) / WORD
- CP = lltype.Ptr(rffi.CArray(lltype.Signed))
- rcp = rffi.cast(CP, read_cache[0])
- if rcp[index] == objint:
- return gcref_struct
- elif self.stmcat == 'Q2R':
- # is GCFLAG_PUBLIC_TO_PRIVATE or GCFLAG_MOVED set?
- if not (objhdr.h_tid &
- (StmGC.GCFLAG_PUBLIC_TO_PRIVATE | StmGC.GCFLAG_MOVED)):
- # no.
- return gcref_struct
- else: # A2I
- # GCFLAG_STUB set?
- if not (objhdr.h_tid & StmGC.GCFLAG_STUB):
- return gcref_struct
-
- funcptr = self.get_barrier_funcptr(returns_modified_object)
- res = funcptr(objadr)
- return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
-
-
-class STMWriteBarrierDescr(STMBarrierDescr):
- def __init__(self, gc_ll_descr, stmcat):
- assert stmcat in ['A2W', 'V2W', 'A2V']
- func = {'A2W':'stm_WriteBarrier',
- 'V2W':'stm_RepeatWriteBarrier',
- 'A2V':'stm_WriteBarrier',
- }
-
- STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- func[stmcat])
-
-
- @specialize.arg(2)
- def _do_barrier(self, gcref_struct, returns_modified_object):
- assert returns_modified_object
- from rpython.memory.gc.stmgc import StmGC
- objadr = llmemory.cast_ptr_to_adr(gcref_struct)
- objhdr = rffi.cast(StmGC.GCHDRP, gcref_struct)
-
- # for A2W, we check h_revision and WRITE_BARRIER
- # for V2W, we only check WRITE_BARRIER
- # for A2V, we only check h_revision
-
- # if it is a repeated WB or h_revision == privat_rev of transaction
- priv_rev = self.llop1.stm_get_adr_of_private_rev_num(rffi.SIGNEDP)
- if self.stmcat == 'V2W' or objhdr.h_revision == priv_rev[0]:
- # also WRITE_BARRIER not set?
- if (self.stmcat == 'A2V'
- or not (objhdr.h_tid & StmGC.GCFLAG_WRITE_BARRIER)):
- return gcref_struct
-
- funcptr = self.get_barrier_funcptr(returns_modified_object)
- res = funcptr(objadr)
- return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
-
-
class GcLLDescr_framework(GcLLDescription):
DEBUG = False # forced to True by x86/test/test_zrpy_gc.py
kind = 'framework'
@@ -551,7 +380,6 @@
def _initialize_for_tests(self):
self.layoutbuilder = None
self.fielddescr_tid = AbstractDescr()
- self.fielddescr_rev = AbstractDescr()
self.max_size_of_young_obj = 1000
self.GCClass = None
self.gcheaderbuilder = None
@@ -592,27 +420,17 @@
def _setup_tid(self):
if not self.stm:
self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR,
'tid')
- self.fielddescr_rev = None
else:
+ xxxxxxxx
self.fielddescr_tid = get_field_descr(self, self.GCClass.GCHDR,
'h_tid')
- self.fielddescr_rev = get_field_descr(self, self.GCClass.GCHDR,
- 'h_revision')
-
frame_tid = self.layoutbuilder.get_type_id(jitframe.JITFRAME)
self.translator._jit2gc['frame_tid'] = frame_tid
def _setup_write_barrier(self):
- if self.stm:
- self.A2Rdescr = STMReadBarrierDescr(self, 'A2R')
- self.A2Idescr = STMReadBarrierDescr(self, 'A2I')
- self.Q2Rdescr = STMReadBarrierDescr(self, 'Q2R')
- self.A2Wdescr = STMWriteBarrierDescr(self, 'A2W')
- self.A2Vdescr = STMWriteBarrierDescr(self, 'A2V')
- self.V2Wdescr = STMWriteBarrierDescr(self, 'V2W')
- self.write_barrier_descr = "wbdescr: do not use"
- else:
- self.write_barrier_descr = WriteBarrierDescr(self)
+ self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address], lltype.Void))
+ self.write_barrier_descr = WriteBarrierDescr(self)
def _make_functions(self, really_not_translated):
from rpython.memory.gctypelayout import check_typeid
@@ -775,15 +593,12 @@
hdr.tid = tid
def can_use_nursery_malloc(self, size):
- return (self.max_size_of_young_obj is not None and
- size < self.max_size_of_young_obj)
+ return size < self.max_size_of_young_obj
def has_write_barrier_class(self):
return WriteBarrierDescr
def get_malloc_slowpath_addr(self):
- if self.max_size_of_young_obj is None: # stm
- return None
return self.get_malloc_fn_addr('malloc_nursery')
def get_malloc_slowpath_array_addr(self):
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -59,7 +59,7 @@
if op.is_malloc():
self.handle_malloc_operation(op)
continue
- elif op.can_malloc():
+ elif op.is_call():
self.emitting_an_operation_that_can_collect()
elif op.getopnum() == rop.LABEL:
self.emitting_an_operation_that_can_collect()
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -25,10 +25,9 @@
return
# ---------- transaction breaks ----------
if opnum == rop.STM_TRANSACTION_BREAK:
- # XXX redo!
- #self.emitting_an_operation_that_can_collect()
- #self.next_op_may_be_in_new_transaction()
- #self.newops.append(op)
+ self.emitting_an_operation_that_can_collect()
+ self.next_op_may_be_in_new_transaction()
+ self.newops.append(op)
return
# ---------- pure operations, guards ----------
if op.is_always_pure() or op.is_guard() or op.is_ovf():
@@ -41,6 +40,17 @@
return
# ---------- calls ----------
if op.is_call():
+ if opnum == rop.CALL and op.getdescr():
+ d = op.getdescr()
+ assert isinstance(d, CallDescr)
+ ei = d.get_extra_info()
+ if ei and (ei.oopspecindex ==
+ EffectInfo.OS_JIT_STM_SHOULD_BREAK_TRANSACTION):
+ self.newops.append(op)
+ return
+ #
+ self.next_op_may_be_in_new_transaction()
+ #
if opnum == rop.CALL_RELEASE_GIL:
# self.fallback_inevitable(op)
# is done by assembler._release_gil_shadowstack()
@@ -59,125 +69,41 @@
else:
self.newops.append(op)
return
+ # ---------- setters for pure fields ----------
+ if opnum in (rop.STRSETITEM, rop.UNICODESETITEM):
+ self.handle_setters_for_pure_fields(op)
+ return
# ---------- copystrcontent ----------
if opnum in (rop.COPYSTRCONTENT, rop.COPYUNICODECONTENT):
self.handle_copystrcontent(op)
- continue
- XXX
+ return
# ---------- raw getfields and setfields ----------
if opnum in (rop.GETFIELD_RAW, rop.SETFIELD_RAW):
if self.maybe_handle_raw_accesses(op):
- continue
+ return
# ---------- labels ----------
if opnum == rop.LABEL:
- self.emitting_an_operation_that_can_collect()
+ # note that the parent class also clears some things on a LABEL
self.next_op_may_be_in_new_transaction()
-
self.newops.append(op)
- continue
- # ---------- jumps ----------
- if opnum == rop.JUMP:
+ return
+ # ---------- jumps, finish, other ignored ops ----------
+ if opnum in (rop.JUMP, rop.FINISH, rop.FORCE_TOKEN,
+ rop.READ_TIMESTAMP, rop.MARK_OPAQUE_PTR,
+ rop.JIT_DEBUG, rop.KEEPALIVE,
+ rop.QUASIIMMUT_FIELD, rop.RECORD_KNOWN_CLASS,
+ ):
self.newops.append(op)
- continue
- # ---------- finish, other ignored ops ----------
- if opnum in (rop.FINISH, rop.FORCE_TOKEN,
- rop.READ_TIMESTAMP, rop.MARK_OPAQUE_PTR,
- rop.JIT_DEBUG, rop.KEEPALIVE,
- rop.QUASIIMMUT_FIELD, rop.RECORD_KNOWN_CLASS,
- ):
- self.newops.append(op)
- continue
+ return
# ---------- fall-back ----------
- # Check that none of the ops handled here can_collect
- # or cause a transaction break. This is not done by
- # the fallback here
+ # Check that none of the ops handled here can collect.
+ # This is not done by the fallback here
+ assert not op.is_call() and not op.is_malloc()
self.fallback_inevitable(op)
- debug_print("fallback for", op.repr())
- def emitting_an_operation_that_can_collect(self):
- GcRewriterAssembler.emitting_an_operation_that_can_collect(self)
- self.invalidate_write_categories()
-
def next_op_may_be_in_new_transaction(self):
- self.known_lengths.clear() # XXX: check if really necessary or
- # just for labels
- self.known_category.clear()
self.always_inevitable = False
- def invalidate_write_categories(self):
- for v, c in self.known_category.items():
- if c == 'W':
- self.known_category[v] = 'V'
-
- def invalidate_read_categories(self, reason):
- # XXX: needs aliasing info to be better
- # XXX: move to optimizeopt to only invalidate same typed vars?
- for v, c in self.known_category.items():
- if c == 'R':
- self.known_category[v] = 'Q'
-
-
- def get_barrier_descr(self, from_cat, to_cat):
- # compare with translator.stm.funcgen.stm_barrier
- # XXX: specialize more with info of IMMUTABLE and NOPTR
- if from_cat >= to_cat:
- return None
-
- gc = self.gc_ll_descr
- if to_cat == 'W':
- if from_cat >= 'V':
- return gc.V2Wdescr
- return gc.A2Wdescr
- elif to_cat == 'V':
- return gc.A2Vdescr
- elif to_cat == 'R':
- if from_cat >= 'Q':
- return gc.Q2Rdescr
- return gc.A2Rdescr
- elif to_cat == 'I':
- return gc.A2Idescr
-
- def gen_initialize_tid(self, v_newgcobj, tid):
- GcRewriterAssembler.gen_initialize_tid(self, v_newgcobj, tid)
- if self.gc_ll_descr.fielddescr_rev is not None:
- op = ResOperation(rop.STM_SET_REVISION_GC, [v_newgcobj,], None,
- descr=self.gc_ll_descr.fielddescr_rev)
- self.newops.append(op)
-
- def gen_write_barrier(self, v):
- raise NotImplementedError
-
- def gen_barrier(self, v_base, target_category):
- v_base = self.unconstifyptr(v_base)
- assert isinstance(v_base, BoxPtr)
- source_category = self.known_category.get(v_base, 'A')
- write_barrier_descr = self.get_barrier_descr(source_category,
- target_category)
- if write_barrier_descr is None:
- return v_base # no barrier needed
-
- if target_category in ('W', 'V'):
- # if *any* of the readable vars is the same object,
- # it must repeat the read_barrier now
- self.invalidate_read_categories(v_base)
-
- args = [v_base,]
- op = rop.COND_CALL_STM_B
- self.newops.append(ResOperation(op, args, None,
- descr=write_barrier_descr))
-
- self.known_category[v_base] = target_category
- return v_base
-
- def unconstifyptr(self, v):
- if isinstance(v, ConstPtr):
- v_in = v
- v_out = BoxPtr()
- self.newops.append(ResOperation(rop.SAME_AS, [v_in], v_out))
- v = v_out
- assert isinstance(v, BoxPtr)
- return v
-
def handle_getfields(self, op):
opnum = op.getopnum()
descr = op.getdescr()
@@ -254,6 +180,7 @@
self._do_stm_call('stm_try_inevitable', [], None)
self.always_inevitable = True
self.newops.append(op)
+ debug_print("fallback for", op.repr())
def _is_null(self, box):
return isinstance(box, ConstPtr) and not box.value
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -71,7 +71,6 @@
register_known_gctype(self.cpu, o_vtable, O)
#
tiddescr = self.gc_ll_descr.fielddescr_tid
- revdescr = self.gc_ll_descr.fielddescr_rev
wbdescr = self.gc_ll_descr.write_barrier_descr
WORD = globals()['WORD']
#
@@ -103,11 +102,9 @@
namespace[funcname + '_descr'] = getattr(self.gc_ll_descr,
'%s_descr' % funcname)
#
- ops = parse(frm_operations, namespace=namespace,
- invent_fail_descr=False)
+ ops = parse(frm_operations, namespace=namespace)
expected = parse(to_operations % Evaluator(namespace),
- namespace=namespace,
- invent_fail_descr=False)
+ namespace=namespace)
operations = self.gc_ll_descr.rewrite_assembler(self.cpu,
ops.operations,
[])
@@ -287,7 +284,7 @@
gcdescr = get_description(config_)
self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
really_not_translated=True)
- self.gc_ll_descr.write_barrier_descr.has_barrier_from_array = (
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
lambda cpu: True)
#
class FakeCPU(BaseFakeCPU):
@@ -579,7 +576,7 @@
""")
def test_write_barrier_before_array_without_from_array(self):
- self.gc_ll_descr.write_barrier_descr.has_barrier_from_array = (
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
lambda cpu: False)
self.check_rewrite("""
[p1, i2, p3]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit