Author: Armin Rigo <[email protected]>
Branch: stmgc-c4
Changeset: r65240:cee8eec5ca90
Date: 2013-07-06 21:36 +0200
http://bitbucket.org/pypy/pypy/changeset/cee8eec5ca90/
Log: hg merge
diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py
--- a/pypy/module/thread/stm.py
+++ b/pypy/module/thread/stm.py
@@ -5,7 +5,7 @@
from pypy.module.thread.threadlocals import BaseThreadLocals
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.executioncontext import ExecutionContext
-from pypy.interpreter.gateway import Wrappable, W_Root, interp2app
+from pypy.interpreter.gateway import W_Root, interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty, descr_get_dict
from rpython.rlib import rthread
from rpython.rlib import rstm
@@ -122,7 +122,7 @@
# ____________________________________________________________
-class STMLocal(Wrappable):
+class STMLocal(W_Root):
"""Thread-local data"""
@jit.dont_look_inside
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -92,7 +92,7 @@
self._build_wb_slowpath(False, withfloats=True)
self._build_wb_slowpath(True, withfloats=True)
self._build_propagate_exception_path()
- if gc_ll_descr.get_malloc_slowpath_addr is not None:
+ if gc_ll_descr.get_malloc_slowpath_addr() is not None:
# generate few slowpaths for various cases
self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed')
self.malloc_slowpath_varsize = self._build_malloc_slowpath(
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
@@ -241,6 +241,9 @@
return self.malloc_array(arraydescr.basesize, num_elem,
arraydescr.itemsize,
arraydescr.lendescr.offset)
+
+ def get_malloc_slowpath_addr(self):
+ return None
# ____________________________________________________________
# All code below is for the hybrid or minimark GC
@@ -267,37 +270,24 @@
rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address)
return rffi.cast(lltype.Signed, rst_addr)
+
class WriteBarrierDescr(AbstractDescr):
- def __init__(self, gc_ll_descr, stmcat=None):
+ def __init__(self, gc_ll_descr):
self.llop1 = gc_ll_descr.llop1
- self.stmcat = stmcat
- self.returns_modified_object = (stmcat is not None)
- if not self.returns_modified_object:
- self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
- [llmemory.Address], lltype.Void))
- else:
- self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
- [llmemory.Address], llmemory.Address))
+
+ self.returns_modified_object = False
+ self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address], lltype.Void))
+
self.fielddescr_tid = gc_ll_descr.fielddescr_tid
self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
self.HDRPTR = gc_ll_descr.HDRPTR
#
- if self.stmcat is not None:
- cfunc_name = self.stmcat[2]
- self.wb_failing_case_ptr = rffi.llexternal(
- cfunc_name,
- self.WB_FUNCPTR_MOD.TO.ARGS,
- self.WB_FUNCPTR_MOD.TO.RESULT,
- sandboxsafe=True,
- _nowrapper=True)
- #
GCClass = gc_ll_descr.GCClass
if GCClass is None: # for tests
return
- if self.stmcat is None:
- self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
- else:
- self.jit_wb_if_flag = self.stmcat[0]
+
+ 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))
#
@@ -317,11 +307,7 @@
self.wb_slowpath = [0, 0, 0, 0]
def repr_of_descr(self):
- if self.stmcat is None:
- return 'wbdescr'
- else:
- cat = self.stmcat[1]
- return cat
+ return 'wbdescr'
def __repr__(self):
return '<WriteBarrierDescr %r>' % (self.repr_of_descr(),)
@@ -376,7 +362,7 @@
self.wb_slowpath[withcards + 2 * withfloats] = addr
@specialize.arg(2)
- def _do_write_barrier(self, gcref_struct, returns_modified_object):
+ 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
@@ -392,7 +378,50 @@
if returns_modified_object:
return gcref_struct
+class STMBarrierDescr(WriteBarrierDescr):
+ def __init__(self, gc_ll_descr, stmcat, cfunc_name):
+ WriteBarrierDescr.__init__(self, gc_ll_descr)
+ self.stmcat = stmcat
+ self.returns_modified_object = True
+ self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address], llmemory.Address))
+ self.wb_failing_case_ptr = rffi.llexternal(
+ cfunc_name,
+ self.WB_FUNCPTR_MOD.TO.ARGS,
+ self.WB_FUNCPTR_MOD.TO.RESULT,
+ sandboxsafe=True,
+ _nowrapper=True)
+
+ def repr_of_descr(self):
+ cat = self.stmcat
+ return cat
+
+ @specialize.arg(2)
+ def _do_barrier(self, gcref_struct, returns_modified_object):
+ assert self.returns_modified_object == returns_modified_object
+ # XXX: fastpath for Read and Write variants
+ funcptr = self.get_barrier_funcptr(returns_modified_object)
+ res = funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
+ if returns_modified_object:
+ return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
+
+
+class STMReadBarrierDescr(STMBarrierDescr):
+ def __init__(self, gc_ll_descr, stmcat):
+ assert stmcat == 'P2R'
+ STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
+ 'stm_read_barrier')
+
+
+
+class STMWriteBarrierDescr(STMBarrierDescr):
+ def __init__(self, gc_ll_descr, stmcat):
+ assert stmcat in ['P2W', 'R2W']
+ STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
+ 'stm_write_barrier')
+
+
class GcLLDescr_framework(GcLLDescription):
DEBUG = False # forced to True by x86/test/test_zrpy_gc.py
kind = 'framework'
@@ -487,18 +516,13 @@
else:
self.write_barrier_descr = WriteBarrierDescr(self)
def do_write_barrier(gcref_struct, gcref_newptr):
- self.write_barrier_descr._do_write_barrier(gcref_struct, False)
+ self.write_barrier_descr._do_barrier(gcref_struct, False)
self.do_write_barrier = do_write_barrier
def _setup_barriers_for_stm(self):
- from rpython.memory.gc import stmgc
- WBDescr = WriteBarrierDescr
- self.P2Rdescr = WBDescr(self, (stmgc.GCFLAG_GLOBAL, 'P2R',
- 'stm_DirectReadBarrier'))
- self.P2Wdescr = WBDescr(self, (stmgc.GCFLAG_NOT_WRITTEN, 'P2W',
- 'stm_WriteBarrier'))
- self.R2Wdescr = WBDescr(self, (stmgc.GCFLAG_NOT_WRITTEN, 'R2W',
- 'stm_WriteBarrierFromReady'))
+ self.P2Rdescr = STMReadBarrierDescr(self, 'P2R')
+ self.P2Wdescr = STMWriteBarrierDescr(self, 'P2W')
+ self.R2Wdescr = STMWriteBarrierDescr(self, 'R2W')
self.write_barrier_descr = "wbdescr: do not use"
#
@specialize.argtype(0)
@@ -509,7 +533,7 @@
descr = self.P2Wdescr
else:
descr = self.P2Rdescr
- return descr._do_write_barrier(gcref, True)
+ return descr._do_barrier(gcref, True)
self.do_stm_barrier = do_stm_barrier
def _make_functions(self, really_not_translated):
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
@@ -121,8 +121,13 @@
except KeyError:
return v_base # no barrier needed
args = [v_base, self.c_zero]
- self.newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
+ if target_category == 'W':
+ op = rop.COND_CALL_STM_WB
+ else:
+ op = rop.COND_CALL_STM_RB
+ self.newops.append(ResOperation(op, args, None,
descr=write_barrier_descr))
+
self.known_category[v_base] = target_category
return v_base
diff --git a/rpython/jit/backend/llsupport/test/test_gc.py
b/rpython/jit/backend/llsupport/test/test_gc.py
--- a/rpython/jit/backend/llsupport/test/test_gc.py
+++ b/rpython/jit/backend/llsupport/test/test_gc.py
@@ -213,7 +213,7 @@
gc_ll_descr = self.gc_ll_descr
llop1 = self.llop1
#
- rewriter = gc.GcRewriterAssembler(gc_ll_descr, None)
+ rewriter = GcRewriterAssembler(gc_ll_descr, None)
newops = rewriter.newops
v_base = BoxPtr()
v_value = BoxPtr()
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
@@ -35,6 +35,7 @@
tdescr = get_size_descr(self.gc_ll_descr, T)
tdescr.tid = 5678
tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
+ tydescr = get_field_descr(self.gc_ll_descr, T, 'y')
#
A = lltype.GcArray(lltype.Signed)
adescr = get_array_descr(self.gc_ll_descr, A)
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -1,8 +1,9 @@
from rpython.jit.backend.llsupport.descr import *
from rpython.jit.backend.llsupport.gc import *
from rpython.jit.metainterp.gc import get_description
-from rpython.jit.backend.llsupport.test.test_rewrite import RewriteTests
-
+from rpython.jit.backend.llsupport.test.test_rewrite import (
+ RewriteTests, BaseFakeCPU)
+from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
class TestStm(RewriteTests):
def setup_method(self, meth):
@@ -17,11 +18,12 @@
self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
really_not_translated=True)
#
- class FakeCPU(object):
+ class FakeCPU(BaseFakeCPU):
def sizeof(self, STRUCT):
descr = SizeDescrWithVTable(104)
descr.tid = 9315
return descr
+
self.cpu = FakeCPU()
def check_rewrite(self, frm_operations, to_operations, **namespace):
@@ -42,12 +44,14 @@
jump()
""", """
[p1, p2]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, p2, descr=tzdescr)
jump()
""")
def test_rewrite_setfield_gc_const(self):
+ TP = lltype.GcArray(lltype.Signed)
+ NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP))
self.check_rewrite("""
[p1, p2]
setfield_gc(ConstPtr(t), p2, descr=tzdescr)
@@ -55,10 +59,10 @@
""", """
[p1, p2]
p3 = same_as(ConstPtr(t))
- cond_call_gc_wb(p3, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p3, 0, descr=P2Wdescr)
setfield_gc(p3, p2, descr=tzdescr)
jump()
- """)
+ """, t=NULL)
def test_rewrite_setfield_gc_on_local(self):
self.check_rewrite("""
@@ -83,9 +87,9 @@
jump()
""", """
[p1, p2, p3, p4]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, p2, descr=tzdescr)
- cond_call_gc_wb(p3, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p3, 0, descr=P2Wdescr)
setfield_gc(p3, p4, descr=tzdescr)
jump()
""")
@@ -98,7 +102,7 @@
jump()
""", """
[p1, p2, i3]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, p2, descr=tzdescr)
setfield_gc(p1, i3, descr=tydescr)
jump()
@@ -113,10 +117,10 @@
jump(p1)
""", """
[p1, p2, i3]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, p2, descr=tzdescr)
label(p1, i3)
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, i3, descr=tydescr)
jump(p1)
""")
@@ -158,12 +162,14 @@
jump(p2)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
p2 = getfield_gc(p1, descr=tzdescr)
jump(p2)
""")
def test_rewrite_getfield_gc_const(self):
+ TP = lltype.GcArray(lltype.Signed)
+ NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP))
self.check_rewrite("""
[p1]
p2 = getfield_gc(ConstPtr(t), descr=tzdescr)
@@ -171,10 +177,10 @@
""", """
[p1]
p3 = same_as(ConstPtr(t))
- cond_call_gc_wb(p3, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p3, 0, descr=P2Rdescr)
p2 = getfield_gc(p3, descr=tzdescr)
jump(p2)
- """)
+ """, t=NULL)
# XXX could do better: G2Rdescr
def test_rewrite_getarrayitem_gc(self):
@@ -184,7 +190,7 @@
jump(i3)
""", """
[p1, i2]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
i3 = getarrayitem_gc(p1, i2, descr=adescr)
jump(i3)
""")
@@ -196,7 +202,7 @@
jump(i3)
""", """
[p1, i2]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
i3 = getinteriorfield_gc(p1, i2, descr=adescr)
jump(i3)
""")
@@ -209,7 +215,7 @@
jump(p2, i2)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
p2 = getfield_gc(p1, descr=tzdescr)
i2 = getfield_gc(p1, descr=tydescr)
jump(p2, i2)
@@ -223,9 +229,9 @@
jump(p2, i2)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
p2 = getfield_gc(p1, descr=tzdescr)
- cond_call_gc_wb(p2, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p2, 0, descr=P2Rdescr)
i2 = getfield_gc(p2, descr=tydescr)
jump(p2, i2)
""")
@@ -241,10 +247,10 @@
jump(p1)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
i1 = getfield_gc(p1, descr=tydescr)
i2 = int_add(i1, 1)
- cond_call_gc_wb(p1, 0, descr=R2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=R2Wdescr)
setfield_gc(p1, i2, descr=tydescr)
jump(p1)
""")
@@ -257,7 +263,7 @@
jump(p2)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, 123, descr=tydescr)
p2 = getfield_gc(p1, descr=tzdescr)
jump(p2)
@@ -289,10 +295,10 @@
jump(p2)
""", """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
p2 = getfield_gc(p1, descr=tzdescr)
call(p2)
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, 5, descr=tydescr)
jump(p2)
""")
@@ -300,62 +306,62 @@
def test_getfield_raw(self):
self.check_rewrite("""
[i1, i2]
- i3 = getfield_raw(i1, descr=?)
+ i3 = getfield_raw(i1, descr=tydescr)
keepalive(i3) # random ignored operation
- i4 = getfield_raw(i2, descr=?)
+ i4 = getfield_raw(i2, descr=tydescr)
jump(i3, i4)
""", """
[i1, i2]
$INEV
- i3 = getfield_raw(i1, descr=?)
+ i3 = getfield_raw(i1, descr=tydescr)
keepalive(i3)
- i4 = getfield_raw(i2, descr=?)
+ i4 = getfield_raw(i2, descr=tydescr)
jump(i3, i4)
""")
def test_getfield_raw_over_label(self):
self.check_rewrite("""
[i1, i2]
- i3 = getfield_raw(i1, descr=?)
+ i3 = getfield_raw(i1, descr=tydescr)
label(i1, i2, i3)
- i4 = getfield_raw(i2, descr=?)
+ i4 = getfield_raw(i2, descr=tydescr)
jump(i3, i4)
""", """
[i1, i2]
$INEV
- i3 = getfield_raw(i1, descr=?)
+ i3 = getfield_raw(i1, descr=tydescr)
label(i1, i2, i3)
$INEV
- i4 = getfield_raw(i2, descr=?)
+ i4 = getfield_raw(i2, descr=tydescr)
jump(i3, i4)
""")
def test_getarrayitem_raw(self):
self.check_rewrite("""
[i1, i2]
- i3 = getarrayitem_raw(i1, 5, descr=?)
- i4 = getarrayitem_raw(i2, i3, descr=?)
+ i3 = getarrayitem_raw(i1, 5, descr=adescr)
+ i4 = getarrayitem_raw(i2, i3, descr=adescr)
jump(i3, i4)
""", """
[i1, i2]
$INEV
- i3 = getarrayitem_raw(i1, 5, descr=?)
- i4 = getarrayitem_raw(i2, i3, descr=?)
+ i3 = getarrayitem_raw(i1, 5, descr=adescr)
+ i4 = getarrayitem_raw(i2, i3, descr=adescr)
jump(i3, i4)
""")
def test_rewrite_unrelated_setarrayitem_gcs(self):
self.check_rewrite("""
[p1, i1, p2, p3, i3, p4]
- setarrayitem_gc(p1, i1, p2, descr=?)
- setarrayitem_gc(p3, i3, p4, descr=?)
+ setarrayitem_gc(p1, i1, p2, descr=adescr)
+ setarrayitem_gc(p3, i3, p4, descr=adescr)
jump()
""", """
[p1, i1, p2, p3, i3, p4]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
- setarrayitem_gc(p1, i1, p2, descr=?)
- cond_call_gc_wb(p3, 0, descr=P2Wdescr)
- setarrayitem_gc(p3, i3, p4, descr=?)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+ setarrayitem_gc(p1, i1, p2, descr=adescr)
+ cond_call_stm_wb(p3, 0, descr=P2Wdescr)
+ setarrayitem_gc(p3, i3, p4, descr=adescr)
jump()
""")
@@ -368,7 +374,7 @@
jump()
""", """
[p1, p2, i2, p3, i3]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setarrayitem_gc(p1, i2, p2, descr=adescr)
i4 = read_timestamp()
setarrayitem_gc(p1, i3, p3, descr=adescr)
@@ -384,7 +390,7 @@
jump()
""", """
[p1, p2, i2, p3, i3]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setinteriorfield_gc(p1, i2, p2, descr=adescr)
i4 = read_timestamp()
setinteriorfield_gc(p1, i3, p3, descr=adescr)
@@ -399,7 +405,7 @@
jump()
""", """
[p1, i2, i3]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
strsetitem(p1, i2, i3)
unicodesetitem(p1, i2, i3)
jump()
@@ -408,10 +414,12 @@
"that p1 is already a W")
def test_fallback_to_inevitable(self):
+ T = rffi.CArrayPtr(rffi.TIME_T)
+ calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T)
oplist = [
- "setfield_raw(i1, i2, descr=?)",
- "setarrayitem_raw(i1, i2, i3, descr=?)",
- "setinteriorfield_raw(i1, i2, i3, descr=?)",
+ "setfield_raw(i1, i2, descr=tydescr)",
+ "setarrayitem_raw(i1, i2, i3, descr=tydescr)",
+ "setinteriorfield_raw(i1, i2, i3, descr=adescr)",
"call_release_gil(123, descr=calldescr2)",
"escape(i1)", # a generic unknown operation
]
@@ -424,14 +432,14 @@
jump(i2, p7)
""" % op, """
[i1, i2, i3, p7]
- cond_call_gc_wb(p7, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p7, 0, descr=P2Wdescr)
setfield_gc(p7, 10, descr=tydescr)
$INEV
%s
- cond_call_gc_wb(p7, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p7, 0, descr=P2Wdescr)
setfield_gc(p7, 20, descr=tydescr)
jump(i2, p7)
- """ % op)
+ """ % op, calldescr2=calldescr2)
def test_copystrcontent(self):
self.check_rewrite("""
@@ -440,8 +448,8 @@
jump()
""", """
[p1, p2, i1, i2, i3]
- cond_call_gc_wb(p2, 0, descr=P2Wdescr)
- cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+ cond_call_stm_wb(p2, 0, descr=P2Wdescr)
+ cond_call_stm_rb(p1, 0, descr=P2Rdescr)
copystrcontent(p1, p2, i1, i2, i3)
jump()
""")
@@ -460,7 +468,7 @@
jump(p1)
""" % op, """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, 10, descr=tydescr)
%s
setfield_gc(p1, 20, descr=tydescr)
@@ -468,8 +476,10 @@
""" % op)
def test_call_force(self):
+ T = rffi.CArrayPtr(rffi.TIME_T)
+ calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T)
for op in ["call(123, descr=calldescr2)",
- "call_assembler(123, descr=loopdescr)",
+ "call_assembler(123, descr=casmdescr)",
"call_may_force(123, descr=calldescr2)",
"call_loopinvariant(123, descr=calldescr2)",
]:
@@ -481,13 +491,13 @@
jump(p1)
""" % op, """
[p1]
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, 10, descr=tydescr)
%s
- cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+ cond_call_stm_wb(p1, 0, descr=P2Wdescr)
setfield_gc(p1, 20, descr=tydescr)
jump(p1)
- """ % op)
+ """ % op, calldescr2=calldescr2)
def test_ptr_eq_null(self):
self.check_rewrite("""
diff --git a/rpython/jit/backend/test/runner_test.py
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -4242,3 +4242,14 @@
assert rffi.cast(lltype.Signed, a[0]) == -7654
assert rffi.cast(lltype.Signed, a[1]) == 777
lltype.free(a, flavor='raw')
+
+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/rpython/jit/metainterp/executor.py
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -345,6 +345,8 @@
if value in (rop.FORCE_TOKEN,
rop.CALL_ASSEMBLER,
rop.COND_CALL_GC_WB,
+ rop.COND_CALL_STM_WB,
+ rop.COND_CALL_STM_RB,
rop.COND_CALL_GC_WB_ARRAY,
rop.DEBUG_MERGE_POINT,
rop.JIT_DEBUG,
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -500,6 +500,8 @@
'STRSETITEM/3',
'UNICODESETITEM/3',
#'RUNTIMENEW/1', # ootype operation
+ 'COND_CALL_STM_WB/2d', # [objptr, newvalue] (write barrier)
+ 'COND_CALL_STM_RB/2d', # [objptr, newvalue] (read barrier)
'COND_CALL_GC_WB/2d', # [objptr, newvalue] (for the write barrier)
'COND_CALL_GC_WB_ARRAY/3d', # [objptr, arrayindex, newvalue] (write barr.)
'DEBUG_MERGE_POINT/*', # debugging only
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -8,6 +8,27 @@
from rpython.rtyper.lltypesystem import rffi
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rlib.debug import ll_assert
+from rpython.rlib.rarithmetic import LONG_BIT, r_uint
+
+WORD = LONG_BIT // 8
+NULL = llmemory.NULL
+
+# keep in sync with stmgc.h & et.h:
+first_gcflag = 1 << (LONG_BIT//2)
+GCFLAG_OLD = first_gcflag << 0
+GCFLAG_VISITED = first_gcflag << 1
+GCFLAG_PUBLIC = first_gcflag << 2
+GCFLAG_PREBUILT_ORIGINAL = first_gcflag << 3
+GCFLAG_PUBLIC_TO_PRIVATE = first_gcflag << 4
+GCFLAG_WRITE_BARRIER = first_gcflag << 5 # stmgc.h
+GCFLAG_NURSERY_MOVED = first_gcflag << 6
+GCFLAG_BACKUP_COPY = first_gcflag << 7 # debug
+GCFLAG_STUB = first_gcflag << 8 # debug
+GCFLAG_PRIVATE_FROM_PROTECTED = first_gcflag << 9
+GCFLAG_HAS_ID = first_gcflag << 10
+
+PREBUILT_FLAGS = first_gcflag * (1 + 2 + 4 + 8)
+PREBUILT_REVISION = r_uint(1)
class StmGC(MovingGCBase):
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -1,5 +1,5 @@
from rpython.rlib.objectmodel import we_are_translated, specialize
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
+from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rtyper.extregistry import ExtRegistryEntry
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -584,34 +584,34 @@
from rpython.translator.stm.funcgen import op_stm
self.__class__.op_stm = op_stm
return self.op_stm(op)
- OP_STM_INITIALIZE = _OP_STM
- OP_STM_FINALIZE = _OP_STM
- OP_STM_BECOME_INEVITABLE = _OP_STM
- OP_STM_BARRIER = _OP_STM
- OP_STM_PTR_EQ = _OP_STM
- OP_STM_PUSH_ROOT = _OP_STM
- OP_STM_POP_ROOT_INTO = _OP_STM
- OP_STM_ALLOCATE = _OP_STM
- OP_STM_GET_TID = _OP_STM
- OP_STM_HASH = _OP_STM
- OP_STM_ID = _OP_STM
- OP_STM_COMMIT_TRANSACTION = _OP_STM
+ OP_STM_INITIALIZE = _OP_STM
+ OP_STM_FINALIZE = _OP_STM
+ OP_STM_BECOME_INEVITABLE = _OP_STM
+ OP_STM_BARRIER = _OP_STM
+ OP_STM_PTR_EQ = _OP_STM
+ OP_STM_PUSH_ROOT = _OP_STM
+ OP_STM_POP_ROOT_INTO = _OP_STM
+ OP_STM_ALLOCATE = _OP_STM
+ OP_STM_GET_TID = _OP_STM
+ OP_STM_HASH = _OP_STM
+ OP_STM_ID = _OP_STM
+ OP_STM_COMMIT_TRANSACTION = _OP_STM
OP_STM_BEGIN_INEVITABLE_TRANSACTION = _OP_STM
- OP_STM_SHOULD_BREAK_TRANSACTION = _OP_STM
- OP_STM_SET_TRANSACTION_LENGTH = _OP_STM
- OP_STM_CHANGE_ATOMIC = _OP_STM
- OP_STM_GET_ATOMIC = _OP_STM
- OP_STM_THREADLOCAL_GET = _OP_STM
- OP_STM_THREADLOCAL_SET = _OP_STM
- OP_STM_PERFORM_TRANSACTION = _OP_STM
- OP_STM_ENTER_CALLBACK_CALL = _OP_STM
- OP_STM_LEAVE_CALLBACK_CALL = _OP_STM
- OP_STM_ABORT_AND_RETRY = _OP_STM
- OP_STM_ABORT_INFO_PUSH = _OP_STM
- OP_STM_ABORT_INFO_POP = _OP_STM
- OP_STM_INSPECT_ABORT_INFO = _OP_STM
- OP_STM_MINOR_COLLECT = _OP_STM
- OP_STM_MAJOR_COLLECT = _OP_STM
+ OP_STM_SHOULD_BREAK_TRANSACTION = _OP_STM
+ OP_STM_SET_TRANSACTION_LENGTH = _OP_STM
+ OP_STM_CHANGE_ATOMIC = _OP_STM
+ OP_STM_GET_ATOMIC = _OP_STM
+ OP_STM_THREADLOCAL_GET = _OP_STM
+ OP_STM_THREADLOCAL_SET = _OP_STM
+ OP_STM_PERFORM_TRANSACTION = _OP_STM
+ OP_STM_ENTER_CALLBACK_CALL = _OP_STM
+ OP_STM_LEAVE_CALLBACK_CALL = _OP_STM
+ OP_STM_ABORT_AND_RETRY = _OP_STM
+ OP_STM_ABORT_INFO_PUSH = _OP_STM
+ OP_STM_ABORT_INFO_POP = _OP_STM
+ OP_STM_INSPECT_ABORT_INFO = _OP_STM
+ OP_STM_MAJOR_COLLECT = _OP_STM
+ OP_STM_MINOR_COLLECT = _OP_STM
def OP_PTR_NONZERO(self, op):
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -141,11 +141,11 @@
translator = self.translator
if self.config.translation.stm:
- from rpython.translator.stm import transform2
+ from rpython.translator.stm import transform
self.getentrypointptr() # build the wrapper first
# ^^ this is needed to make sure we see the no-GC wrapper function
# calling the GC entrypoint function.
- stmtransformer = transform2.STMTransformer(self.translator)
+ stmtransformer = transform.STMTransformer(self.translator)
stmtransformer.transform()
gcpolicyclass = self.get_gcpolicyclass()
diff --git a/rpython/translator/stm/test/test_inevitable.py
b/rpython/translator/stm/test/test_inevitable.py
--- a/rpython/translator/stm/test/test_inevitable.py
+++ b/rpython/translator/stm/test/test_inevitable.py
@@ -160,7 +160,7 @@
extfunc()
res = self.interpret_inevitable(f1, [])
- assert res == 'direct_call'
+ assert res == 'extfunc()'
def test_rpy_direct_call(self):
def f2():
diff --git a/rpython/translator/stm/test/test_jitdriver.py
b/rpython/translator/stm/test/test_jitdriver.py
--- a/rpython/translator/stm/test/test_jitdriver.py
+++ b/rpython/translator/stm/test/test_jitdriver.py
@@ -1,5 +1,5 @@
from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.translator.stm.test.transform2_support import BaseTestTransform
+from rpython.translator.stm.test.transform_support import BaseTestTransform
from rpython.rlib.jit import JitDriver
diff --git a/rpython/translator/stm/test/test_stmgcintf.c
b/rpython/translator/stm/test/test_stmgcintf.c
--- a/rpython/translator/stm/test/test_stmgcintf.c
+++ b/rpython/translator/stm/test/test_stmgcintf.c
@@ -11,6 +11,7 @@
struct pypy_header0 {
long h_tid;
Unsigned h_revision;
+ Unsigned h_original;
};
struct pypy_pypy_rlib_rstm_Transaction0 {
@@ -33,7 +34,8 @@
#define _RPyString_AsString(x) x
#define RPyString_Size(x) strlen(x)
-
+#include "src_stm/stmgc.h"
+#include "src_stm/stmimpl.h"
#include "src_stm/et.h"
#include "src_stm/et.c"
diff --git a/rpython/translator/stm/test/test_writebarrier.py
b/rpython/translator/stm/test/test_writebarrier.py
--- a/rpython/translator/stm/test/test_writebarrier.py
+++ b/rpython/translator/stm/test/test_writebarrier.py
@@ -1,5 +1,5 @@
from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.translator.stm.test.transform2_support import BaseTestTransform
+from rpython.translator.stm.test.transform_support import BaseTestTransform
class TestTransform(BaseTestTransform):
diff --git a/rpython/translator/stm/test/test_ztranslated.py
b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -133,12 +133,16 @@
rgc.collect(0)
return 0
#
+ from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+ S = lltype.GcStruct('S', ('got_exception', OBJECTPTR))
+ PS = lltype.Ptr(S)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
class X:
def __init__(self, count):
self.count = count
def g():
x = X(1000)
- perform_transaction(lltype.malloc(FOOBAR))
+ perform_transaction(lltype.malloc(S))
return x
def entry_point(argv):
x = X(len(argv))
@@ -146,7 +150,7 @@
print '<', x.count, y.count, '>'
return 0
#
- perform_transaction = rstm.make_perform_transaction(check, FOOBARP)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
t, cbuilder = self.compile(entry_point, backendopt=True)
data = cbuilder.cmdexec('a b c d')
assert '< 5 1000 >' in data, "got: %r" % (data,)
@@ -160,11 +164,15 @@
pass
prebuilt2 = [X2(), X2()]
#
+ from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+ S = lltype.GcStruct('S', ('got_exception', OBJECTPTR))
+ PS = lltype.Ptr(S)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
def bug2(count):
x = prebuilt2[count]
x.foobar = 2 # 'x' becomes a local
#
- perform_transaction(lltype.malloc(FOOBAR))
+ perform_transaction(lltype.malloc(S))
# 'x' becomes the global again
#
y = prebuilt2[count] # same prebuilt obj
@@ -176,7 +184,7 @@
print bug2(1)
return 0
#
- perform_transaction = rstm.make_perform_transaction(check, FOOBARP)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
t, cbuilder = self.compile(entry_point, backendopt=True)
data = cbuilder.cmdexec('')
assert '12\n12\n' in data, "got: %r" % (data,)
@@ -184,6 +192,12 @@
def test_prebuilt_nongc(self):
def check(foobar, retry_counter):
return 0 # do nothing
+ from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+ from rpython.rtyper.lltypesystem import lltype
+ S = lltype.GcStruct('S', ('got_exception', OBJECTPTR))
+ PS = lltype.Ptr(S)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
+
from rpython.rtyper.lltypesystem import lltype
R = lltype.GcStruct('R', ('x', lltype.Signed))
S1 = lltype.Struct('S1', ('r', lltype.Ptr(R)))
@@ -192,7 +206,7 @@
# hints={'stm_thread_local': True})
#s2 = lltype.malloc(S2, immortal=True, flavor='raw')
def do_stuff():
- perform_transaction(lltype.malloc(FOOBAR))
+ perform_transaction(lltype.malloc(S))
print s1.r.x
#print s2.r.x
do_stuff._dont_inline_ = True
@@ -204,7 +218,7 @@
do_stuff()
return 0
#
- perform_transaction = rstm.make_perform_transaction(check, FOOBARP)
+ perform_transaction = rstm.make_perform_transaction(check, PS)
t, cbuilder = self.compile(main)
data = cbuilder.cmdexec('')
assert '42\n' in data, "got: %r" % (data,)
@@ -262,9 +276,3 @@
t, cbuilder = self.compile(main)
data = cbuilder.cmdexec('a b')
assert 'li102ee10:hi there 3e\n0\n' in data
-
-
-FOOBAR = lltype.GcStruct('FOOBAR',
- ('result_value', lltype.Void),
- ('got_exception', rclass.OBJECTPTR))
-FOOBARP = lltype.Ptr(FOOBAR)
diff --git a/rpython/translator/stm/test/transform2_support.py
b/rpython/translator/stm/test/transform_support.py
rename from rpython/translator/stm/test/transform2_support.py
rename to rpython/translator/stm/test/transform_support.py
--- a/rpython/translator/stm/test/transform2_support.py
+++ b/rpython/translator/stm/test/transform_support.py
@@ -1,7 +1,7 @@
from rpython.rtyper.lltypesystem import lltype, opimpl
from rpython.rtyper.llinterp import LLFrame
from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache
-from rpython.translator.stm.transform2 import STMTransformer
+from rpython.translator.stm.transform import STMTransformer
from rpython.translator.stm.writebarrier import MORE_PRECISE_CATEGORIES
from rpython.conftest import option
diff --git a/rpython/translator/stm/transform2.py
b/rpython/translator/stm/transform.py
rename from rpython/translator/stm/transform2.py
rename to rpython/translator/stm/transform.py
--- a/rpython/translator/stm/transform2.py
+++ b/rpython/translator/stm/transform.py
@@ -1,3 +1,10 @@
+from rpython.translator.backendopt.writeanalyze import WriteAnalyzer
+from rpython.translator.stm.writebarrier import insert_stm_barrier
+from rpython.translator.stm.inevitable import insert_turn_inevitable
+from rpython.translator.stm.jitdriver import reorganize_around_jit_driver
+from rpython.translator.stm.threadlocalref import transform_tlref
+from rpython.translator.c.support import log
+
class STMTransformer(object):
@@ -18,38 +25,27 @@
self.print_logs_after_gc()
def transform_write_barrier(self):
- from rpython.translator.backendopt.writeanalyze import WriteAnalyzer
- from rpython.translator.stm.writebarrier import insert_stm_barrier
- #
self.write_analyzer = WriteAnalyzer(self.translator)
for graph in self.translator.graphs:
insert_stm_barrier(self, graph)
del self.write_analyzer
def transform_turn_inevitable(self):
- from rpython.translator.stm.inevitable import insert_turn_inevitable
- #
for graph in self.translator.graphs:
insert_turn_inevitable(graph)
def transform_jit_driver(self):
- from rpython.translator.stm.jitdriver import
reorganize_around_jit_driver
- #
for graph in self.translator.graphs:
reorganize_around_jit_driver(self, graph)
def transform_threadlocalref(self):
- from rpython.translator.stm.threadlocalref import transform_tlref
transform_tlref(self.translator)
def start_log(self):
- from rpython.translator.c.support import log
log.info("Software Transactional Memory transformation")
def print_logs(self):
- from rpython.translator.c.support import log
log.info("Software Transactional Memory transformation applied")
def print_logs_after_gc(self):
- from rpython.translator.c.support import log
log.info("Software Transactional Memory transformation-after-gc done")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit