[pypy-commit] pypy stm-gc: In-progress.
arigo
noreply at buildbot.pypy.org
Tue Feb 7 16:53:10 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52186:99247048a1de
Date: 2012-02-07 16:11 +0100
http://bitbucket.org/pypy/pypy/changeset/99247048a1de/
Log: In-progress.
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -75,7 +75,7 @@
"markcompact": [("translation.gctransformer", "framework")],
"minimark": [("translation.gctransformer", "framework")],
"stmgc": [("translation.gctransformer", "framework"),
- ("translation.gcrootfinder", "none")], # XXX
+ ("translation.gcrootfinder", "stm")],
},
cmdline="--gc"),
ChoiceOption("gctransformer", "GC transformer that is used - internal",
@@ -93,7 +93,7 @@
default=IS_64_BITS, cmdline="--gcremovetypeptr"),
ChoiceOption("gcrootfinder",
"Strategy for finding GC Roots (framework GCs only)",
- ["n/a", "shadowstack", "asmgcc", "none"],
+ ["n/a", "shadowstack", "asmgcc", "stm"],
"shadowstack",
cmdline="--gcrootfinder",
requires={
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
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory, llarena, llgroup, rffi
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage
from pypy.rpython.memory.gc.base import GCBase
@@ -34,6 +34,7 @@
_alloc_flavor_ = "raw"
inline_simple_malloc = True
inline_simple_malloc_varsize = True
+ needs_custom_readers = "stm"
needs_write_barrier = "stm"
prebuilt_gc_objects_are_static_roots = False
malloc_zero_filled = True # xxx?
@@ -80,12 +81,13 @@
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)
- GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address],lltype.Signed))
self.stm_operations.setup_size_getter(
- llhelper(GETSIZE, self._getsize_fn))
+ llhelper(self.GETSIZE, self._getsize_fn))
self.main_thread_tls = self.setup_thread(True)
self.mutex_lock = ll_thread.allocate_ll_lock()
@@ -201,6 +203,11 @@
@always_inline
+ def get_type_id(self, obj):
+ tid = self.header(obj).tid
+ return llop.extract_ushort(llgroup.HALFWORD, tid)
+
+ @always_inline
def combine(self, typeid16, flags):
return llop.combine_ushort(lltype.Signed, typeid16, flags)
@@ -314,6 +321,11 @@
# ----------
+ def identityhash(self, gcref):
+ raise NotImplementedError("XXX")
+
+ # ----------
+
def acquire(self, lock):
ll_thread.c_thread_acquirelock(lock, 1)
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -313,14 +313,6 @@
[s_gc, annmodel.SomeInteger(knowntype=llgroup.r_halfword)],
annmodel.SomeInteger())
- if hasattr(GCClass, 'writebarrier_before_copy'):
- self.wb_before_copy_ptr = \
- getfn(GCClass.writebarrier_before_copy.im_func,
- [s_gc] + [annmodel.SomeAddress()] * 2 +
- [annmodel.SomeInteger()] * 3, annmodel.SomeBool())
- elif GCClass.needs_write_barrier:
- raise NotImplementedError("GC needs write barrier, but does not provide writebarrier_before_copy functionality")
-
# in some GCs we can inline the common case of
# malloc_fixedsize(typeid, size, False, False, False)
if getattr(GCClass, 'inline_simple_malloc', False):
@@ -447,43 +439,8 @@
annmodel.SomeInteger(nonneg=True)],
annmodel.s_None)
- self.write_barrier_ptr = None
- self.write_barrier_from_array_ptr = None
- if GCClass.needs_write_barrier:
- self.write_barrier_ptr = getfn(GCClass.write_barrier.im_func,
- [s_gc,
- annmodel.SomeAddress(),
- annmodel.SomeAddress()],
- annmodel.s_None,
- inline=True)
- func = getattr(gcdata.gc, 'remember_young_pointer', None)
- if func is not None:
- # func should not be a bound method, but a real function
- assert isinstance(func, types.FunctionType)
- self.write_barrier_failing_case_ptr = getfn(func,
- [annmodel.SomeAddress(),
- annmodel.SomeAddress()],
- annmodel.s_None)
- func = getattr(GCClass, 'write_barrier_from_array', None)
- if func is not None:
- self.write_barrier_from_array_ptr = getfn(func.im_func,
- [s_gc,
- annmodel.SomeAddress(),
- annmodel.SomeAddress(),
- annmodel.SomeInteger()],
- annmodel.s_None,
- inline=True)
- func = getattr(gcdata.gc, 'remember_young_pointer_from_array3',
- None)
- if func is not None:
- # func should not be a bound method, but a real function
- assert isinstance(func, types.FunctionType)
- self.write_barrier_from_array_failing_case_ptr = \
- getfn(func,
- [annmodel.SomeAddress(),
- annmodel.SomeInteger(),
- annmodel.SomeAddress()],
- annmodel.s_None)
+ self.setup_write_barriers(GCClass, s_gc)
+
self.statistics_ptr = getfn(GCClass.statistics.im_func,
[s_gc, annmodel.SomeInteger()],
annmodel.SomeInteger())
@@ -525,6 +482,53 @@
from pypy.rpython.memory.gctransform import shadowstack
return shadowstack.ShadowStackRootWalker(self)
+ def setup_write_barriers(self, GCClass, s_gc):
+ self.write_barrier_ptr = None
+ self.write_barrier_from_array_ptr = None
+ if GCClass.needs_write_barrier:
+ self.write_barrier_ptr = getfn(GCClass.write_barrier.im_func,
+ [s_gc,
+ annmodel.SomeAddress(),
+ annmodel.SomeAddress()],
+ annmodel.s_None,
+ inline=True)
+ func = getattr(gcdata.gc, 'remember_young_pointer', None)
+ if func is not None:
+ # func should not be a bound method, but a real function
+ assert isinstance(func, types.FunctionType)
+ self.write_barrier_failing_case_ptr = getfn(func,
+ [annmodel.SomeAddress(),
+ annmodel.SomeAddress()],
+ annmodel.s_None)
+ func = getattr(GCClass, 'write_barrier_from_array', None)
+ if func is not None:
+ self.write_barrier_from_array_ptr = getfn(func.im_func,
+ [s_gc,
+ annmodel.SomeAddress(),
+ annmodel.SomeAddress(),
+ annmodel.SomeInteger()],
+ annmodel.s_None,
+ inline=True)
+ func = getattr(gcdata.gc, 'remember_young_pointer_from_array3',
+ None)
+ if func is not None:
+ # func should not be a bound method, but a real function
+ assert isinstance(func, types.FunctionType)
+ self.write_barrier_from_array_failing_case_ptr = \
+ getfn(func,
+ [annmodel.SomeAddress(),
+ annmodel.SomeInteger(),
+ annmodel.SomeAddress()],
+ annmodel.s_None)
+ if hasattr(GCClass, 'writebarrier_before_copy'):
+ self.wb_before_copy_ptr = \
+ getfn(GCClass.writebarrier_before_copy.im_func,
+ [s_gc] + [annmodel.SomeAddress()] * 2 +
+ [annmodel.SomeInteger()] * 3, annmodel.SomeBool())
+ elif GCClass.needs_write_barrier:
+ raise NotImplementedError("GC needs write barrier, but does not provide writebarrier_before_copy functionality")
+
+
def consider_constant(self, TYPE, value):
self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc)
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -0,0 +1,22 @@
+from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer
+from pypy.translator.backendopt.support import var_needsgc
+
+
+class StmFrameworkGCTransformer(FrameworkGCTransformer):
+
+ def setup_write_barriers(self, GCClass, s_gc):
+ self.write_barrier_ptr = None
+ self.write_barrier_from_array_ptr = None
+ pass # xxx
+
+ def gct_getfield(self, hop):
+ if self.var_needs_set_transform(hop.spaceop.args[0]):
+ hop.rename('stm_' + hop.spaceop.opname)
+ else:
+ self.default(hop)
+ gct_getarrayitem = gct_getfield
+ gct_getinteriorfield = gct_getfield
+
+
+ def gct_gc_writebarrier_before_copy(self, hop):
+ xxx
diff --git a/pypy/rpython/memory/gctransform/test/test_framework.py b/pypy/rpython/memory/gctransform/test/test_framework.py
--- a/pypy/rpython/memory/gctransform/test/test_framework.py
+++ b/pypy/rpython/memory/gctransform/test/test_framework.py
@@ -18,9 +18,13 @@
import py
+class ForTestGCTransformer(FrameworkGCTransformer):
+ root_stack_depth = 100
+
class FrameworkGcPolicy2(FrameworkGcPolicy):
- class transformerclass(FrameworkGCTransformer):
- root_stack_depth = 100
+ @staticmethod
+ def get_transformer_class():
+ return ForTestGCTransformer
def test_framework_simple():
def g(x):
diff --git a/pypy/rpython/memory/gctransform/test/test_stmframework.py b/pypy/rpython/memory/gctransform/test/test_stmframework.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/memory/gctransform/test/test_stmframework.py
@@ -0,0 +1,27 @@
+from pypy.translator.translator import graphof
+from pypy.objspace.flow.model import summary
+from pypy.rpython.memory.gctransform.test.test_transform import rtype
+from pypy.rpython.memory.gctransform.stmframework import (
+ StmFrameworkGCTransformer)
+
+
+def prepare(entrypoint, types, func=None):
+ t = rtype(entrypoint, types)
+ t.config.translation.gc = 'stmgc'
+ transformer = StmFrameworkGCTransformer(t)
+ graph = graphof(t, func or entrypoint)
+ transformer.transform_graph(graph)
+ return t, graph
+
+
+def test_reader():
+ class A(object):
+ def __init__(self, x):
+ self.x = x
+ def f(a1, a2):
+ return a1.x
+ def entry(n, m):
+ return f(A(n), A(m))
+
+ t, graph = prepare(entry, [int, int], f)
+ assert summary(graph) == {'stm_getfield': 1}
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -933,6 +933,7 @@
class TestMarkSweepGC(GenericGCTests):
gcname = "marksweep"
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
GC_PARAMS = {'start_heap_size': 1024*WORD,
'translated_to_c': False}
@@ -943,6 +944,7 @@
gcname = "statistics"
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.marksweep import PrintingMarkSweepGC as GCClass
GC_PARAMS = {'start_heap_size': 1024*WORD,
@@ -954,6 +956,7 @@
GC_CAN_SHRINK_ARRAY = True
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass
GC_PARAMS = {'space_size': 512*WORD,
@@ -964,6 +967,7 @@
gcname = 'markcompact'
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass
GC_PARAMS = {'space_size': 4096*WORD,
@@ -975,6 +979,7 @@
GC_CAN_SHRINK_ARRAY = True
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.generation import GenerationGC as \
GCClass
@@ -1161,6 +1166,7 @@
gcname = "generation"
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.generation import GenerationGC
class GCClass(GenerationGC):
@@ -1206,6 +1212,7 @@
GC_CAN_MALLOC_NONMOVABLE = True
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass
GC_PARAMS = {'space_size': 512*WORD,
@@ -1275,6 +1282,7 @@
GC_CAN_TEST_ID = True
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.minimark import MiniMarkGC as GCClass
GC_PARAMS = {'nursery_size': 32*WORD,
@@ -1391,6 +1399,7 @@
class TestMarkSweepTaggedPointerGC(TaggedPointerGCTests):
gcname = "marksweep"
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
GC_PARAMS = {'start_heap_size': 1024*WORD,
'translated_to_c': False}
@@ -1400,6 +1409,7 @@
gcname = "hybrid"
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.generation import GenerationGC as \
GCClass
@@ -1412,6 +1422,7 @@
gcname = 'markcompact'
class gcpolicy(gc.FrameworkGcPolicy):
+ get_transformer_class = lambda self: self.transformerclass
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass
GC_PARAMS = {'space_size': 4096*WORD,
diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py
--- a/pypy/translator/c/database.py
+++ b/pypy/translator/c/database.py
@@ -60,7 +60,8 @@
else:
self.exctransformer = translator.getexceptiontransformer()
if translator is not None:
- self.gctransformer = self.gcpolicy.transformerclass(translator)
+ transformerclass = self.gcpolicy.get_transformer_class()
+ self.gctransformer = transformerclass(translator)
self.completed = False
self.instrument_ncounter = 0
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -5,8 +5,6 @@
from pypy.rpython.lltypesystem.lltype import \
typeOf, Ptr, ContainerType, RttiStruct, \
RuntimeTypeInfo, getRuntimeTypeInfo, top_container
-from pypy.rpython.memory.gctransform import \
- refcounting, boehm, framework, asmgcroot
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -112,7 +110,10 @@
from pypy.rlib.objectmodel import CDefinedIntSymbolic
class RefcountingGcPolicy(BasicGcPolicy):
- transformerclass = refcounting.RefcountingGCTransformer
+ @staticmethod
+ def get_transformer_class():
+ from pypy.rpython.memory.gctransform import refcounting
+ return refcounting.RefcountingGCTransformer
def common_gcheader_initdata(self, defnode):
if defnode.db.gctransformer is not None:
@@ -197,7 +198,10 @@
class BoehmGcPolicy(BasicGcPolicy):
- transformerclass = boehm.BoehmGCTransformer
+ @staticmethod
+ def get_transformer_class():
+ from pypy.rpython.memory.gctransform import boehm
+ return boehm.BoehmGCTransformer
def common_gcheader_initdata(self, defnode):
if defnode.db.gctransformer is not None:
@@ -247,9 +251,11 @@
yield 'boehm_gc_startup_code();'
def get_real_weakref_type(self):
+ from pypy.rpython.memory.gctransform import boehm
return boehm.WEAKLINK
def convert_weakref_to(self, ptarget):
+ from pypy.rpython.memory.gctransform import boehm
return boehm.convert_weakref_to(ptarget)
def OP_GC__COLLECT(self, funcgen, op):
@@ -306,7 +312,10 @@
class FrameworkGcPolicy(BasicGcPolicy):
- transformerclass = framework.FrameworkGCTransformer
+ @staticmethod
+ def get_transformer_class():
+ from pypy.rpython.memory.gctransform import framework
+ return framework.FrameworkGCTransformer
def struct_setup(self, structdefnode, rtti):
if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
@@ -338,9 +347,11 @@
yield '%s();' % (self.db.get(fnptr),)
def get_real_weakref_type(self):
+ from pypy.rpython.memory.gctransform import framework
return framework.WEAKREF
def convert_weakref_to(self, ptarget):
+ from pypy.rpython.memory.gctransform import framework
return framework.convert_weakref_to(ptarget)
def OP_GC_RELOAD_POSSIBLY_MOVED(self, funcgen, op):
@@ -396,7 +407,10 @@
raise Exception("the FramewokGCTransformer should handle this")
class AsmGcRootFrameworkGcPolicy(FrameworkGcPolicy):
- transformerclass = asmgcroot.AsmGcRootFrameworkGCTransformer
+ @staticmethod
+ def get_transformer_class():
+ from pypy.rpython.memory.gctransform import asmgcroot
+ return asmgcroot.AsmGcRootFrameworkGCTransformer
def GC_KEEPALIVE(self, funcgen, v):
return 'pypy_asm_keepalive(%s);' % funcgen.expr(v)
@@ -404,6 +418,12 @@
def OP_GC_STACK_BOTTOM(self, funcgen, op):
return 'pypy_asm_stack_bottom();'
+class StmFrameworkGcPolicy(FrameworkGcPolicy):
+ @staticmethod
+ def get_transformer_class():
+ from pypy.rpython.memory.gctransform import stmframework
+ return stmframework.StmFrameworkGCTransformer
+
name_to_gcpolicy = {
'boehm': BoehmGcPolicy,
@@ -411,6 +431,5 @@
'none': NoneGcPolicy,
'framework': FrameworkGcPolicy,
'framework+asmgcroot': AsmGcRootFrameworkGcPolicy,
+ 'framework+stm': StmFrameworkGcPolicy,
}
-
-
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,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.gc.stmgc import PRIMITIVE_SIZES
from pypy.translator.stm import _rffi_stm
@@ -28,9 +29,10 @@
lltype.Void)
tldict_enum = smexternal('stm_tldict_enum', [CALLBACK], lltype.Void)
- stm_read_word = smexternal('stm_read_word',
- [llmemory.Address, lltype.Signed],
- lltype.Signed)
+ for _size, _TYPE in PRIMITIVE_SIZES.items():
+ _name = 'stm_read_int%d' % _size
+ locals()[_name] = smexternal(_name, [llmemory.Address, lltype.Signed],
+ _TYPE)
stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
[llmemory.Address,
More information about the pypy-commit
mailing list