Commits

Remi Meier  committed b0c0a83

stm: add stm_dont_track_raw_accesses hint to AroundState and don't turn inevitable before shrink_array
getfield(aroundstate, before) caused us to go inevitable before many ext-calls

  • Participants
  • Parent commits 61c42f8
  • Branches stm-logging

Comments (0)

Files changed (5)

File pypy/rpython/lltypesystem/rclass.py

 #         ...               // extra instance attributes
 #     }
 #
-# there's also a nongcobject 
+# there's also a nongcobject
 
 OBJECT_VTABLE = lltype.ForwardReference()
 CLASSTYPE = Ptr(OBJECT_VTABLE)
         cname = inputconst(Void, mangled_name)
         return llops.genop('getfield', [v_vtable, cname], resulttype=r)
 
-    def rtype_issubtype(self, hop): 
+    def rtype_issubtype(self, hop):
         class_repr = get_type_repr(self.rtyper)
         v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
         if isinstance(v_cls2, Constant):
         else:
             ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]]
             self.object_type = ForwardRef()
-            
+
         self.iprebuiltinstances = identity_dict()
         self.lowleveltype = Ptr(self.object_type)
         self.gcflavor = gcflavor
             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

File pypy/rpython/lltypesystem/rffi.py

 LeaveCallbackFnPtr = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
 class AroundState:
     _alloc_flavor_ = "raw"
+    _stm_dont_track_raw_accesses_ = True
     def _cleanup_(self):
         self.before = None    # or a regular RPython function
         self.after = None     # or a regular RPython function
             b.append(cp[i])
             i += 1
         return assert_str0(b.build())
+    charp2str._always_inline_ = 'try'
 
     # str -> char*
     # Can't inline this because of the raw address manipulation.

File pypy/rpython/rclass.py

     """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):
     try:
 def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
     from pypy.rlib.objectmodel import UnboxedValue
     from pypy.objspace.flow.model import Constant
-    
+
     if classdef is None:
         unboxed = []
         virtualizable2 = False
             if self.classdef.commonbase(subclassdef) != self.classdef:
                 raise TyperError("not a subclass of %r: %r" % (
                     self.classdef.name, desc))
-        
+
         r_subclass = getclassrepr(self.rtyper, subclassdef)
         return r_subclass.getruntime(self.lowleveltype)
 
             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'

File pypy/translator/stm/inevitable.py

 
     'weakref_create', 'weakref_deref',
     'nop',
+    'shrink_array',
     ])
 ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops())
 
         return False
     if S._hints.get('stm_dont_track_raw_accesses', False):
         return False
+
     return not fresh_mallocs.is_fresh_malloc(op.args[0])
 
 def should_turn_inevitable(op, block, fresh_mallocs):

File pypy/translator/stm/test/test_inevitable.py

         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