Author: Armin Rigo <[email protected]>
Branch: stmgc-c4
Changeset: r65097:039f1f916424
Date: 2013-06-29 16:05 +0200
http://bitbucket.org/pypy/pypy/changeset/039f1f916424/
Log: in-progress
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
new file mode 100644
--- /dev/null
+++ b/rpython/memory/gc/stmgc.py
@@ -0,0 +1,73 @@
+"""
+Minimal GC interface for STM. The actual GC is implemented in C code,
+from rpython/translator/stm/src_stm/.
+"""
+
+from rpython.memory.gc.base import MovingGCBase
+from rpython.rtyper.lltypesystem import lltype, llmemory, llgroup, rffi
+from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rlib.debug import ll_assert
+
+
+class PrebuiltStmGCHeader(llmemory.Symbolic):
+ def __init__(self, typeid16):
+ self.typeid16 = typeid16
+ def annotation(self):
+ from rpython.annotator import model
+ return model.SomePtr(self.lltype())
+ def lltype(self):
+ return lltype.Ptr(StmGC.HDR)
+
+
+class StmGC(MovingGCBase):
+ _alloc_flavor_ = "raw"
+ inline_simple_malloc = True
+ inline_simple_malloc_varsize = True
+ needs_write_barrier = True
+ prebuilt_gc_objects_are_static_roots = False
+ malloc_zero_filled = True
+ #gcflag_extra = GCFLAG_EXTRA
+
+ HDR = rffi.COpaque('struct stm_object_s')
+ typeid_is_in_field = None
+
+ TRANSLATION_PARAMS = {}
+
+ def get_type_id(self, obj):
+ return llop.stm_get_tid(llgroup.HALFWORD, obj)
+
+ def init_gc_object_immortal(self, addr, typeid16, flags=0):
+ assert flags == 0
+ return PrebuiltStmGCHeader(typeid16)
+
+ def malloc_fixedsize_clear(self, typeid, size,
+ needs_finalizer=False,
+ is_finalizer_light=False,
+ contains_weakptr=False):
+ ll_assert(not needs_finalizer, 'XXX')
+ ll_assert(not is_finalizer_light, 'XXX')
+ ll_assert(not contains_weakptr, 'XXX')
+ return llop.stm_allocate(llmemory.GCREF, size, typeid)
+
+ def malloc_varsize_clear(self, typeid, length, size, itemsize,
+ offset_to_length):
+ ll_assert(False, 'XXX')
+ return llop.stm_allocate(llmemory.GCREF)
+
+ def collect(self, gen=1):
+ """Do a minor (gen=0) or major (gen>0) collection."""
+ if gen > 0:
+ llop.stm_major_collect(lltype.Void)
+ else:
+ llop.stm_minor_collect(lltype.Void)
+
+ def writebarrier_before_copy(self, source_addr, dest_addr,
+ source_start, dest_start, length):
+ ll_assert(False, 'XXX')
+ return False
+
+ def id(self, gcobj):
+ return llop.stm_id(lltype.Signed, gcobj)
+
+ def identityhash(self, gcobj):
+ return llop.stm_hash(lltype.Signed, gcobj)
diff --git a/rpython/memory/gctransform/stmframework.py
b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -1,205 +1,5 @@
from rpython.memory.gctransform import shadowstack
-from rpython.memory.gctransform.framework import BaseRootWalker
-from rpython.memory.gctransform.framework import sizeofaddr
-from rpython.rtyper.lltypesystem import lltype, llmemory
-from rpython.rtyper import rmodel
-from rpython.annotator import model as annmodel
-from rpython.rlib.debug import fatalerror_notb
-from rpython.rlib.nonconst import NonConstant
-from rpython.rlib.objectmodel import specialize
-
-
-END_MARKER = -8 # keep in sync with src_stm/rpyintf.c
class StmFrameworkGCTransformer(shadowstack.ShadowStackFrameworkGCTransformer):
-
- def _declare_functions(self, GCClass, getfn, s_gc, *args):
- super(StmFrameworkGCTransformer, self)._declare_functions(
- GCClass, getfn, s_gc, *args)
- self.stm_start_ptr = getfn(
- self.gcdata.gc.start_transaction.im_func,
- [s_gc], annmodel.s_None)
- self.stm_stop_ptr = getfn(
- self.gcdata.gc.stop_transaction.im_func,
- [s_gc], annmodel.s_None)
-## self.stm_writebarrier_ptr = getfn(
-## self.gcdata.gc.stm_writebarrier,
-## [annmodel.SomeAddress()], annmodel.SomeAddress())
-## self.stm_normalize_global_ptr = getfn(
-## self.gcdata.gc.stm_normalize_global,
-## [annmodel.SomeAddress()], annmodel.SomeAddress())
-## self.write_barrier_failing_case_ptr = getfn(
-## self.gcdata.gc._stm_write_barrier_global,
-## [annmodel.SomeAddress()], annmodel.SomeAddress())
-
- def build_root_walker(self):
- return StmShadowStackRootWalker(self)
-
- def _gc_adr_of_gcdata_attr(self, hop, attrname):
- x = self.root_walker.stackgcdata
- c_const_stackgcdata = rmodel.inputconst(lltype.typeOf(x), x)
- op = hop.spaceop
- ofs = llmemory.offsetof(c_const_stackgcdata.concretetype.TO,
- attrname)
- c_ofs = rmodel.inputconst(lltype.Signed, ofs)
- v_gcdata_adr = hop.genop('cast_ptr_to_adr', [c_const_stackgcdata],
- resulttype=llmemory.Address)
- hop.genop('adr_add', [v_gcdata_adr, c_ofs], resultvar=op.result)
-
-## def gct_stm_writebarrier(self, hop):
-## op = hop.spaceop
-## v_adr = hop.genop('cast_ptr_to_adr',
-## [op.args[0]], resulttype=llmemory.Address)
-## v_localadr = hop.genop("direct_call",
-## [self.stm_writebarrier_ptr, v_adr],
-## resulttype=llmemory.Address)
-## hop.genop('cast_adr_to_ptr', [v_localadr], resultvar=op.result)
-
-## def gct_stm_normalize_global(self, hop):
-## op = hop.spaceop
-## v_adr = hop.genop('cast_ptr_to_adr',
-## [op.args[0]], resulttype=llmemory.Address)
-## v_globaladr = hop.genop("direct_call",
-## [self.stm_normalize_global_ptr, v_adr],
-## resulttype=llmemory.Address)
-## hop.genop('cast_adr_to_ptr', [v_globaladr], resultvar=op.result)
-
- def gct_stm_start_transaction(self, hop):
- livevars = self.push_roots(hop)
- hop.genop("direct_call", [self.stm_start_ptr, self.c_const_gc])
- self.pop_roots(hop, livevars)
-
- def gct_stm_stop_transaction(self, hop):
- livevars = self.push_roots(hop)
- hop.genop("direct_call", [self.stm_stop_ptr, self.c_const_gc])
- self.pop_roots(hop, livevars)
-
-## def gct_gc_store(self, hop):
-## hop.rename('stm_gc_store')
-
-
-class StmShadowStackRootWalker(BaseRootWalker):
- need_root_stack = True
- root_stack_depth = 163840
-
- def __init__(self, gctransformer):
- from rpython.memory.gctransform import shadowstack
- #
- BaseRootWalker.__init__(self, gctransformer)
- # we use the thread-local self.stackgcdata to store state;
- # 'self' is frozen.
- STACKGCDATA = lltype.Struct('STACKGCDATA',
- ('root_stack_top', llmemory.Address),
- ('root_stack_base', llmemory.Address),
- hints={'stm_thread_local': True})
- stackgcdata = lltype.malloc(STACKGCDATA, immortal=True)
- self.stackgcdata = stackgcdata
-
- def incr_stack(n):
- top = stackgcdata.root_stack_top
- stackgcdata.root_stack_top = top + n*sizeofaddr
- return top
- self.incr_stack = incr_stack
-
- def decr_stack(n):
- top = stackgcdata.root_stack_top - n*sizeofaddr
- stackgcdata.root_stack_top = top
- return top
- self.decr_stack = decr_stack
-
- root_iterator = shadowstack.get_root_iterator(gctransformer)
- @specialize.argtype(1)
- def walk_stack_root(callback, arg, end):
- root_iterator.setcontext(NonConstant(llmemory.NULL))
- gc = self.gc
- addr = end
- while True:
- addr = root_iterator.nextleft(gc, llmemory.NULL, addr)
- if addr.signed[0] == END_MARKER:
- break
- callback(arg, addr)
- return addr
- self.rootstackhook = walk_stack_root
-
- rsd = gctransformer.root_stack_depth
- if rsd is not None:
- self.root_stack_depth = rsd
-
- def need_thread_support(self, gctransformer, getfn):
- gc = gctransformer.gcdata.gc
- #
- def gc_thread_start():
- self.allocate_shadow_stack()
- gc.setup_thread()
- #
- def gc_thread_die():
- gc.teardown_thread()
- self.free_shadow_stack()
- #
- self.thread_start_ptr = getfn(
- gc_thread_start,
- [], annmodel.s_None)
- self.thread_die_ptr = getfn(
- gc_thread_die,
- [], annmodel.s_None)
-
- def setup_root_walker(self):
- self.allocate_shadow_stack()
- self.gcdata.main_thread_stack_base = self.stackgcdata.root_stack_base
- BaseRootWalker.setup_root_walker(self)
-
- def allocate_shadow_stack(self):
- root_stack_size = sizeofaddr * self.root_stack_depth
- base = llmemory.raw_malloc(root_stack_size)
- if base == llmemory.NULL:
- raise MemoryError
- base.signed[0] = END_MARKER
- shift = llmemory.sizeof(llmemory.Address)
- self.stackgcdata.root_stack_base = base
- self.stackgcdata.root_stack_top = base + shift
-
- def free_shadow_stack(self):
- base = self.stackgcdata.root_stack_base
- llmemory.raw_free(base)
-
- def walk_roots(self, c1, c2, c3):
- raise NotImplementedError
-
- def walk_stack_roots(self, *args):
- "NOT_RPYTHON"
- raise NotImplementedError
-
- @specialize.argtype(2)
- def walk_current_stack_roots(self, collect_stack_root, arg):
- stackgcdata = self.stackgcdata
- self.rootstackhook(collect_stack_root, arg,
- stackgcdata.root_stack_top)
-
- @specialize.argtype(2)
- def walk_current_nongc_roots(self, collect_nongc_root, arg):
- gcdata = self.gcdata
- gc = self.gc
- addr = gcdata.static_root_start
- end = gcdata.static_root_nongcend
- while addr != end:
- result = addr.address[0]
- if gc.points_to_valid_gc_object(result):
- collect_nongc_root(arg, result)
- addr += sizeofaddr
-
- @specialize.argtype(2)
- def walk_all_stack_roots(self, collect_stack_root, arg):
- # assume that we have the ll_global_lock here
- stmtls = self.gc.linked_list_stmtls
- while stmtls is not None:
- # for every stmtls:
- root_stack_base = stmtls.adr_of_stack_base.address[0]
- root_stack_top = stmtls.adr_of_stack_top.address[0]
- # we walk all segments of the shadow stack, each of them
- # with an END_MARKER at the bottom, until we reach the
- # marker that is at root_stack_base.
- while root_stack_top != root_stack_base:
- root_stack_top = self.rootstackhook(collect_stack_root, arg,
- root_stack_top)
- stmtls = stmtls.linked_list_next
+ pass
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -422,21 +422,13 @@
# to keep them as operations until the genc stage)
'stm_barrier': LLOp(sideeffects=False),
- 'stm_read_barrier': LLOp(), # explicit read barrier, special case
- 'stm_write_barrier': LLOp(), # explicit write barrier, special case
+ 'stm_allocate': LLOp(sideeffects=False),
'stm_become_inevitable': LLOp(),
- 'stm_ptr_eq': LLOp(sideeffects=False),
- 'stm_start_transaction': LLOp(canrun=True, canmallocgc=True),
- 'stm_stop_transaction': LLOp(canrun=True, canmallocgc=True),
- #'stm_jit_invoke_code': LLOp(canmallocgc=True),
- 'stm_threadlocalref_get': LLOp(sideeffects=False),
- 'stm_threadlocalref_set': LLOp(),
- 'stm_threadlocalref_llset': LLOp(),
- 'stm_threadlocalref_llcount': LLOp(sideeffects=False),
- 'stm_threadlocalref_lladdr': LLOp(sideeffects=False),
- 'stm_abort_info_push': LLOp(),
- 'stm_extraref_llcount': LLOp(sideeffects=False),
- 'stm_extraref_lladdr': LLOp(sideeffects=False),
+ 'stm_minor_collect': LLOp(),
+ 'stm_major_collect': LLOp(),
+ 'stm_get_tid': LLOp(canfold=True),
+ 'stm_id': LLOp(sideeffects=False),
+ 'stm_hash': LLOp(sideeffects=False),
# __________ address operations __________
diff --git a/rpython/translator/stm/funcgen.py
b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -19,13 +19,13 @@
assert type(category_change) is str and len(category_change) == 3 # "x2y"
arg = funcgen.expr(op.args[1])
result = funcgen.expr(op.result)
- return '%s = STM_BARRIER_%s(%s);' % (result, category_change, arg)
+ return '%s = stm_barrier_%s(%s);' % (result, category_change, arg)
def stm_ptr_eq(funcgen, op):
arg0 = funcgen.expr(op.args[0])
arg1 = funcgen.expr(op.args[1])
result = funcgen.expr(op.result)
- return '%s = STM_PTR_EQ(%s, %s);' % (result, arg0, arg1)
+ return '%s = stm_pointer_equal(%s, %s);' % (result, arg0, arg1)
def stm_become_inevitable(funcgen, op):
try:
@@ -33,7 +33,7 @@
except IndexError:
info = "rstm.become_inevitable" # cannot insert it in 'llop'
string_literal = c_string_constant(info)
- return 'BecomeInevitable(%s);' % (string_literal,)
+ return 'stm_become_inevitable(%s);' % (string_literal,)
##def stm_jit_invoke_code(funcgen, op):
## return funcgen.OP_DIRECT_CALL(op)
diff --git a/rpython/translator/stm/stmgcintf.py
b/rpython/translator/stm/stmgcintf.py
--- a/rpython/translator/stm/stmgcintf.py
+++ b/rpython/translator/stm/stmgcintf.py
@@ -9,7 +9,7 @@
eci = ExternalCompilationInfo(
include_dirs = [cdir, cdir2],
- includes = ['src_stm/et.h'],
+ includes = ['src_stm/stmgc.h'],
pre_include_bits = ['#define PYPY_LONG_BIT %d' % LONG_BIT,
'#define RPY_STM 1'],
)
diff --git a/rpython/translator/stm/test/support.py
b/rpython/translator/stm/test/support.py
--- a/rpython/translator/stm/test/support.py
+++ b/rpython/translator/stm/test/support.py
@@ -4,12 +4,11 @@
class CompiledSTMTests(StandaloneTests):
- gc = "stmgc"
def compile(self, entry_point, **kwds):
from pypy.config.pypyoption import get_pypy_config
self.config = get_pypy_config(translating=True)
- self.config.translation.gc = self.gc
+ self.config.translation.gc = "stmgc"
self.config.translation.stm = True
#
# Prevent the RaiseAnalyzer from just emitting "WARNING: Unknown
@@ -22,7 +21,3 @@
finally:
RaiseAnalyzer.fail_on_unknown_operation = False
return res
-
-
-class NoGcCompiledSTMTests(CompiledSTMTests):
- gc = "none"
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
@@ -3,19 +3,25 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
-from rpython.translator.stm.test.support import NoGcCompiledSTMTests
from rpython.translator.stm.test.support import CompiledSTMTests
from rpython.translator.stm.test import targetdemo2
-class TestNoGcSTMTranslated(NoGcCompiledSTMTests):
- def test_nogc_targetdemo(self):
- t, cbuilder = self.compile(targetdemo2.entry_point)
- data, dataerr = cbuilder.cmdexec('4 100', err=True)
- assert 'check ok!' in data
+class TestSTMTranslated(CompiledSTMTests):
-
-class TestSTMTranslated(CompiledSTMTests):
+ def test_malloc(self):
+ class Foo:
+ pass
+ def entry_point(argv):
+ lst = []
+ for i in range(int(argv[1])):
+ lst.append(Foo())
+ print '<', len(lst), '>'
+ return 0
+ #
+ t, cbuilder = self.compile(entry_point, backendopt=True)
+ data = cbuilder.cmdexec('42')
+ assert '< 42 >' in data, "got: %r" % (data,)
def test_targetdemo(self):
t, cbuilder = self.compile(targetdemo2.entry_point)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit