[pypy-commit] pypy stmgc-c4: add stm_dont_track_raw_accesses hint for classes; use it for 'aroundstate'

Raemi noreply at buildbot.pypy.org
Mon Jul 29 11:29:05 CEST 2013


Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r65773:ba7123a9d332
Date: 2013-07-29 11:21 +0200
http://bitbucket.org/pypy/pypy/changeset/ba7123a9d332/

Log:	add stm_dont_track_raw_accesses hint for classes; use it for
	'aroundstate' also mark ExcData to not track. this may require
	clearing it on abort!

diff --git a/rpython/rtyper/lltypesystem/rclass.py b/rpython/rtyper/lltypesystem/rclass.py
--- a/rpython/rtyper/lltypesystem/rclass.py
+++ b/rpython/rtyper/lltypesystem/rclass.py
@@ -367,6 +367,7 @@
             if hints is None:
                 hints = {}
             hints = self._check_for_immutable_hints(hints)
+            hints = self._check_for_stm_hints(hints)
             kwds = {}
             if self.gcflavor == 'gc':
                 kwds['rtti'] = True
diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -329,6 +329,7 @@
 
 class AroundState:
     _alloc_flavor_ = "raw"
+    _stm_dont_track_raw_accesses_ = True
 
     def _cleanup_(self):
         self.before = None        # or a regular RPython function
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -46,6 +46,10 @@
 class ImmutableConflictError(Exception):
     """Raised when the _immutable_ or _immutable_fields_ hints are
     not consistent across a class hierarchy."""
+    
+class StmHintConflictError(Exception):
+    """Raised when the _stm_dont_track_raw_accesses_ hints are
+    not consistent across a class hierarchy."""
 
 
 def getclassrepr(rtyper, classdef):
@@ -215,6 +219,26 @@
             hints['immutable_fields'] = accessor
         return hints
 
+    def _check_for_stm_hints(self, hints):
+        loc = self.classdef.classdesc.lookup('_stm_dont_track_raw_accesses_')
+        if loc is not None:
+            if loc is not self.classdef.classdesc:
+                raise StmHintConflictError(
+                    "class %r inherits from its parent"
+                    " _immutable__stm_dont_track_raw_accesses_=True, "
+                    "so it should also declare"
+                    " _stm_dont_track_raw_accesses_=True" % (
+                    self.classdef,))
+            if loc.classdict.get('_stm_dont_track_raw_accesses_').value is not True:
+                raise TyperError(
+                    "class %r: _stm_dont_track_raw_accesses_ = something "
+                    "else than True" % (
+                    self.classdef,))
+            hints = hints.copy()
+            hints['stm_dont_track_raw_accesses'] = True
+        return hints
+
+
     def __repr__(self):
         if self.classdef is None:
             clsname = 'object'
diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py
--- a/rpython/translator/exceptiontransform.py
+++ b/rpython/translator/exceptiontransform.py
@@ -470,7 +470,8 @@
         EXCDATA = lltype.Struct('ExcData',
             ('exc_type',  self.lltype_of_exception_type),
             ('exc_value', self.lltype_of_exception_value),
-            hints={'stm_thread_local': True})
+            hints={'stm_thread_local': True,
+                   'stm_dont_track_raw_accesses':True})
         self.EXCDATA = EXCDATA
 
         exc_data = lltype.malloc(EXCDATA, immortal=True)
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
@@ -224,4 +224,22 @@
         res = self.interpret_inevitable(f1, [True])
         assert res is None
 
+    def test_raw_class_hint(self):
+        class A:
+            _alloc_flavor_ = "raw"
+            _stm_dont_track_raw_accesses_ = True
+            def __init__(self): self.x = 1
 
+        def f2():
+            return A()
+
+        def f(i):
+            a = f2()
+            a.x = i
+            i = a.x
+            lltype.free(a, flavor='raw')
+            return i
+
+        res = self.interpret_inevitable(f, [2])
+        assert res == 'free' # not setfield or getfield
+


More information about the pypy-commit mailing list