[pypy-commit] pypy stm-gc: Fix fix fix.
arigo
noreply at buildbot.pypy.org
Thu Feb 9 18:16:31 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52324:1509515879ae
Date: 2012-02-09 18:16 +0100
http://bitbucket.org/pypy/pypy/changeset/1509515879ae/
Log: Fix fix fix.
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -12,6 +12,7 @@
@specialize.memo()
def _get_stm_callback(func, argcls):
def _stm_callback(llarg, retry_counter):
+ llop.stm_start_transaction(lltype.Void)
if we_are_translated():
llarg = rffi.cast(rclass.OBJECTPTR, llarg)
arg = cast_base_ptr_to_instance(argcls, llarg)
@@ -19,6 +20,7 @@
arg = lltype.TLS.stm_callback_arg
res = func(arg, retry_counter)
assert res is None
+ llop.stm_commit_transaction(lltype.Void)
return lltype.nullptr(rffi.VOIDP.TO)
return _stm_callback
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -395,13 +395,15 @@
# direct_calls and maybe several casts, but it looks less heavy-weight
# to keep them as operations until the genc stage)
- 'stm_getfield': LLOp(sideeffects=False, canrun=True),
- 'stm_getarrayitem': LLOp(sideeffects=False, canrun=True),
- 'stm_getinteriorfield': LLOp(sideeffects=False, canrun=True),
- 'stm_become_inevitable':LLOp(),
- 'stm_descriptor_init': LLOp(),
- 'stm_descriptor_done': LLOp(),
- 'stm_writebarrier': LLOp(sideeffects=False),
+ 'stm_getfield': LLOp(sideeffects=False, canrun=True),
+ 'stm_getarrayitem': LLOp(sideeffects=False, canrun=True),
+ 'stm_getinteriorfield': LLOp(sideeffects=False, canrun=True),
+ 'stm_become_inevitable': LLOp(),
+ 'stm_descriptor_init': LLOp(),
+ 'stm_descriptor_done': LLOp(),
+ 'stm_writebarrier': LLOp(sideeffects=False),
+ 'stm_start_transaction': LLOp(),
+ 'stm_commit_transaction': LLOp(),
# __________ address operations __________
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -22,6 +22,9 @@
4: rffi.INT,
8: lltype.SignedLongLong}
+CALLBACK = lltype.Ptr(lltype.FuncType([llmemory.Address] * 3, lltype.Void))
+GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
+
def always_inline(fn):
fn._always_inline_ = True
@@ -81,13 +84,11 @@
## self.declare_reader(size, TYPE)
self.declare_write_barrier()
- GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
-
def setup(self):
"""Called at run-time to initialize the GC."""
GCBase.setup(self)
self.stm_operations.setup_size_getter(
- llhelper(self.GETSIZE, self._getsize_fn))
+ llhelper(GETSIZE, self._getsize_fn))
self.main_thread_tls = self.setup_thread(True)
self.mutex_lock = ll_thread.allocate_ll_lock()
@@ -217,6 +218,12 @@
def collect(self, gen=0):
raise NotImplementedError
+ def start_transaction(self):
+ self.collector.start_transaction()
+
+ def commit_transaction(self):
+ self.collector.commit_transaction()
+
@always_inline
def get_type_id(self, obj):
@@ -428,20 +435,27 @@
tls.pending_list = NULL
# Enumerate the roots, which are the local copies of global objects.
# For each root, trace it.
- self.stm_operations.enum_tldict_start()
- while self.stm_operations.enum_tldict_find_next():
- globalobj = self.stm_operations.enum_tldict_globalobj()
- localobj = self.stm_operations.enum_tldict_localobj()
- #
- localhdr = self.header(localobj)
- ll_assert(localhdr.version == globalobj,
- "in a root: localobj.version != globalobj")
- ll_assert(localhdr.tid & GCFLAG_GLOBAL == 0,
- "in a root: unexpected GCFLAG_GLOBAL")
- ll_assert(localhdr.tid & GCFLAG_WAS_COPIED != 0,
- "in a root: missing GCFLAG_WAS_COPIED")
- #
- self.trace_and_drag_out_of_nursery(tls, localobj)
+ callback = llhelper(CALLBACK, self._enum_entries)
+ # xxx hack hack hack! Stores 'self' in a global place... but it's
+ # pointless after translation because 'self' is a Void.
+ _global_collector.collector = self
+ self.stm_operations.tldict_enum(callback)
+
+
+ @staticmethod
+ def _enum_entries(tls_addr, globalobj, localobj):
+ self = _global_collector.collector
+ tls = llmemory.cast_adr_to_ptr(tls_addr, lltype.Ptr(StmGC.GCTLS))
+ #
+ localhdr = self.header(localobj)
+ ll_assert(localhdr.version == globalobj,
+ "in a root: localobj.version != globalobj")
+ ll_assert(localhdr.tid & GCFLAG_GLOBAL == 0,
+ "in a root: unexpected GCFLAG_GLOBAL")
+ ll_assert(localhdr.tid & GCFLAG_WAS_COPIED != 0,
+ "in a root: missing GCFLAG_WAS_COPIED")
+ #
+ self.trace_and_drag_out_of_nursery(tls, localobj)
def collect_from_pending_list(self, tls):
@@ -519,3 +533,8 @@
#
# Fix the original root.address[0] to point to the globalobj
root.address[0] = globalobj
+
+
+class _GlobalCollector(object):
+ pass
+_global_collector = _GlobalCollector()
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -1,6 +1,6 @@
import py
from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi
-from pypy.rpython.memory.gc.stmgc import StmGC, PRIMITIVE_SIZES, WORD
+from pypy.rpython.memory.gc.stmgc import StmGC, PRIMITIVE_SIZES, WORD, CALLBACK
from pypy.rpython.memory.gc.stmgc import GCFLAG_GLOBAL, GCFLAG_WAS_COPIED
@@ -37,7 +37,6 @@
assert not hasattr(self, '_tls_dict')
self._tls_dict = {0: tls}
self._tldicts = {0: {}}
- self._tldicts_iterators = {}
self._transactional_copies = []
else:
assert in_main_thread == 0
@@ -64,32 +63,11 @@
assert obj not in tldict
tldict[obj] = localobj
- def enum_tldict_start(self):
- it = self._tldicts[self.threadnum].iteritems()
- self._tldicts_iterators[self.threadnum] = [it, None, None]
-
- def enum_tldict_find_next(self):
- state = self._tldicts_iterators[self.threadnum]
- try:
- next_key, next_value = state[0].next()
- except StopIteration:
- state[1] = None
- state[2] = None
- del self._tldicts_iterators[self.threadnum]
- return False
- state[1] = next_key
- state[2] = next_value
- return True
-
- def enum_tldict_globalobj(self):
- state = self._tldicts_iterators[self.threadnum]
- assert state[1] is not None
- return state[1]
-
- def enum_tldict_localobj(self):
- state = self._tldicts_iterators[self.threadnum]
- assert state[2] is not None
- return state[2]
+ def tldict_enum(self, callback):
+ assert lltype.typeOf(callback) == CALLBACK
+ tls = self.get_tls()
+ for key, value in self._tldicts[self.threadnum].iteritems():
+ callback(tls, key, value)
def _get_stm_reader(size, TYPE):
assert rffi.sizeof(TYPE) == size
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -18,6 +18,12 @@
self.stm_writebarrier_ptr = getfn(
self.gcdata.gc.stm_writebarrier,
[annmodel.SomeAddress()], annmodel.SomeAddress())
+ self.stm_start_ptr = getfn(
+ self.gcdata.gc.start_transaction.im_func,
+ [s_gc], annmodel.s_None)
+ self.stm_commit_ptr = getfn(
+ self.gcdata.gc.commit_transaction.im_func,
+ [s_gc], annmodel.s_None)
def push_roots(self, hop, keep_current_args=False):
pass
@@ -44,6 +50,12 @@
resulttype=llmemory.Address)
hop.genop('cast_adr_to_ptr', [v_localadr], resultvar=op.result)
+ def gct_stm_start_transaction(self, hop):
+ hop.genop("direct_call", [self.stm_start_ptr, self.c_const_gc])
+
+ def gct_stm_commit_transaction(self, hop):
+ hop.genop("direct_call", [self.stm_commit_ptr, self.c_const_gc])
+
class StmStackRootWalker(BaseRootWalker):
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -789,14 +789,15 @@
redolog_insert(&d->redolog, key, value);
}
-void stm_tldict_enum(void(*callback)(void*, void*))
+void stm_tldict_enum(void(*callback)(void*, void*, void*))
{
struct tx_descriptor *d = thread_descriptor;
wlog_t *item;
+ void *tls = stm_get_tls();
REDOLOG_LOOP_FORWARD(d->redolog, item)
{
- callback(item->addr, item->val);
+ callback(tls, item->addr, item->val);
} REDOLOG_LOOP_END;
}
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -20,7 +20,7 @@
void *stm_tldict_lookup(void *);
void stm_tldict_add(void *, void *);
-void stm_tlidct_enum(void(*)(void*, void*));
+void stm_tldict_enum(void(*)(void*, void*, void*));
char stm_read_int1(void *, long);
short stm_read_int2(void *, long);
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
--- a/pypy/translator/stm/stmgcintf.py
+++ b/pypy/translator/stm/stmgcintf.py
@@ -1,14 +1,11 @@
from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.memory.gc.stmgc import PRIMITIVE_SIZES
+from pypy.rpython.memory.gc.stmgc import PRIMITIVE_SIZES, GETSIZE, CALLBACK
from pypy.translator.stm import _rffi_stm
def smexternal(name, args, result):
return staticmethod(_rffi_stm.llexternal(name, args, result))
-CALLBACK = lltype.Ptr(lltype.FuncType([llmemory.Address] * 2, lltype.Void))
-GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
-
class StmOperations(object):
diff --git a/pypy/translator/stm/test/test_stmgcintf.py b/pypy/translator/stm/test/test_stmgcintf.py
--- a/pypy/translator/stm/test/test_stmgcintf.py
+++ b/pypy/translator/stm/test/test_stmgcintf.py
@@ -77,7 +77,8 @@
return content
def get_callback(self):
- def callback(key, value):
+ def callback(tls, key, value):
+ assert tls == llmemory.cast_ptr_to_adr(self.tls)
seen.append((key, value))
seen = []
p_callback = llhelper(CALLBACK, callback)
@@ -88,6 +89,19 @@
stm_operations.tldict_enum(p_callback)
assert seen == []
+ def test_enum_tldict_nonempty(self):
+ a1 = rffi.cast(llmemory.Address, 0x4020)
+ a2 = rffi.cast(llmemory.Address, 10002)
+ a3 = rffi.cast(llmemory.Address, 0x4028)
+ a4 = rffi.cast(llmemory.Address, 10004)
+ #
+ stm_operations.tldict_add(a1, a2)
+ stm_operations.tldict_add(a3, a4)
+ p_callback, seen = self.get_callback()
+ stm_operations.tldict_enum(p_callback)
+ assert (seen == [(a1, a2), (a3, a4)] or
+ seen == [(a3, a4), (a1, a2)])
+
def stm_read_case(self, flags, copied=False):
# doesn't test STM behavior, but just that it appears to work
s1 = lltype.malloc(S1, flavor='raw')
More information about the pypy-commit
mailing list