Author: Armin Rigo <[email protected]>
Branch: cffi-handle-lifetime
Changeset: r80112:235bc9c680e7
Date: 2015-10-11 19:29 +0200
http://bitbucket.org/pypy/pypy/changeset/235bc9c680e7/

Log:    Implement nonmovable=True

diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -915,10 +915,13 @@
         return [op0, op1]
 
     def rewrite_op_malloc(self, op):
-        if op.args[1].value['flavor'] == 'raw':
+        d = op.args[1].value
+        if d.get('nonmovable', False):
+            raise UnsupportedMallocFlags(d)
+        if d.value['flavor'] == 'raw':
             return self._rewrite_raw_malloc(op, 'raw_malloc_fixedsize', [])
         #
-        if op.args[1].value.get('zero', False):
+        if d.value.get('zero', False):
             zero = True
         else:
             zero = False
diff --git a/rpython/memory/gc/generation.py b/rpython/memory/gc/generation.py
--- a/rpython/memory/gc/generation.py
+++ b/rpython/memory/gc/generation.py
@@ -170,7 +170,10 @@
     def malloc_fixedsize_clear(self, typeid, size,
                                has_finalizer=False,
                                is_finalizer_light=False,
-                               contains_weakptr=False):
+                               contains_weakptr=False,
+                               nonmovable=False):
+        if nonmovable:
+            raise MemoryError
         if (has_finalizer or
             (raw_malloc_usage(size) > self.lb_young_fixedsize and
              raw_malloc_usage(size) > self.largest_young_fixedsize)):
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -587,7 +587,8 @@
     def malloc_fixedsize(self, typeid, size,
                                needs_finalizer=False,
                                is_finalizer_light=False,
-                               contains_weakptr=False):
+                               contains_weakptr=False,
+                               nonmovable=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         rawtotalsize = raw_malloc_usage(totalsize)
@@ -603,7 +604,7 @@
         # If totalsize is greater than nonlarge_max (which should never be
         # the case in practice), ask for a rawmalloc.  The following check
         # should be constant-folded.
-        elif rawtotalsize > self.nonlarge_max:
+        elif rawtotalsize > self.nonlarge_max or nonmovable:
             ll_assert(not contains_weakptr,
                       "'contains_weakptr' specified for a large object")
             obj = self.external_malloc(typeid, 0)
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -509,7 +509,8 @@
     def malloc_fixedsize_clear(self, typeid, size,
                                needs_finalizer=False,
                                is_finalizer_light=False,
-                               contains_weakptr=False):
+                               contains_weakptr=False,
+                               nonmovable=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         rawtotalsize = raw_malloc_usage(totalsize)
@@ -525,7 +526,7 @@
         # If totalsize is greater than nonlarge_max (which should never be
         # the case in practice), ask for a rawmalloc.  The following check
         # should be constant-folded.
-        elif rawtotalsize > self.nonlarge_max:
+        elif rawtotalsize > self.nonlarge_max or nonmovable:
             ll_assert(not contains_weakptr,
                       "'contains_weakptr' specified for a large object")
             obj = self.external_malloc(typeid, 0)
diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py
--- a/rpython/memory/gc/semispace.py
+++ b/rpython/memory/gc/semispace.py
@@ -98,7 +98,10 @@
     def malloc_fixedsize_clear(self, typeid16, size,
                                has_finalizer=False,
                                is_finalizer_light=False,
-                               contains_weakptr=False):
+                               contains_weakptr=False,
+                               nonmovable=False):
+        if nonmovable:
+            raise MemoryError
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         result = self.free
diff --git a/rpython/memory/gctransform/framework.py 
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -305,6 +305,7 @@
                 annmodel.SomeInteger(nonneg=True),
                 annmodel.SomeBool(),
                 annmodel.SomeBool(),
+                annmodel.SomeBool(),
                 annmodel.SomeBool()], s_gcref,
                 inline = False)
             self.malloc_varsize_ptr = getfn(
@@ -320,6 +321,7 @@
                  annmodel.SomeInteger(nonneg=True),
                  annmodel.SomeBool(),
                  annmodel.SomeBool(),
+                 annmodel.SomeBool(),
                  annmodel.SomeBool()], s_gcref,
                 inline = False)
             self.malloc_varsize_ptr = getfn(
@@ -363,7 +365,7 @@
             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)
+        # malloc_fixedsize(typeid, size, False, False, False, False)
         if getattr(GCClass, 'inline_simple_malloc', False):
             # make a copy of this function so that it gets annotated
             # independently and the constants are folded inside
@@ -382,7 +384,7 @@
                 malloc_fast,
                 [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True),
-                 s_False, s_False, s_False], s_gcref,
+                 s_False, s_False, s_False, s_False], s_gcref,
                 inline = True)
         else:
             self.malloc_fast_ptr = None
@@ -759,15 +761,19 @@
 
         if not op.opname.endswith('_varsize') and not flags.get('varsize'):
             zero = flags.get('zero', False)
+            c_nonmovable = rmodel.inputconst(lltype.Bool,
+                                             flags.get('nonmovable', False))
             if (self.malloc_fast_ptr is not None and
                 not c_has_finalizer.value and
+                not c_nonmovable.value and
                 (self.malloc_fast_is_clearing or not zero)):
                 malloc_ptr = self.malloc_fast_ptr
             else:
                 malloc_ptr = self.malloc_fixedsize_ptr
             args = [self.c_const_gc, c_type_id, c_size,
                     c_has_finalizer, c_has_light_finalizer,
-                    rmodel.inputconst(lltype.Bool, False)]
+                    rmodel.inputconst(lltype.Bool, False),
+                    c_nonmovable]
         else:
             assert not c_has_finalizer.value
             info_varsize = self.layoutbuilder.get_info_varsize(type_id)
@@ -908,11 +914,12 @@
         [v_typeid, v_size,
          v_has_finalizer, v_has_light_finalizer, v_contains_weakptr] = op.args
         livevars = self.push_roots(hop)
+        c_nonmovable = rmodel.inputconst(lltype.Bool, False)
         hop.genop("direct_call",
                   [self.malloc_fixedsize_ptr, self.c_const_gc,
                    v_typeid, v_size,
                    v_has_finalizer, v_has_light_finalizer,
-                   v_contains_weakptr],
+                   v_contains_weakptr, c_nonmovable],
                   resultvar=op.result)
         self.pop_roots(hop, livevars)
 
@@ -1018,8 +1025,9 @@
         malloc_ptr = self.malloc_fixedsize_ptr
         c_false = rmodel.inputconst(lltype.Bool, False)
         c_has_weakptr = rmodel.inputconst(lltype.Bool, True)
+        c_nonmovable = rmodel.inputconst(lltype.Bool, False)
         args = [self.c_const_gc, c_type_id, c_size,
-                c_false, c_false, c_has_weakptr]
+                c_false, c_false, c_has_weakptr, c_nonmovable]
 
         # push and pop the current live variables *including* the argument
         # to the weakref_create operation, which must be kept alive and
diff --git a/rpython/memory/test/test_transformed_gc.py 
b/rpython/memory/test/test_transformed_gc.py
--- a/rpython/memory/test/test_transformed_gc.py
+++ b/rpython/memory/test/test_transformed_gc.py
@@ -1247,6 +1247,21 @@
         res = self.runner('nursery_hash_base')
         assert res([]) >= 195
 
+    def define_instantiate_nonmovable(cls):
+        from rpython.rlib import objectmodel
+        from rpython.rtyper import annlowlevel
+        class A:
+            pass
+        def fn():
+            a = objectmodel.instantiate(A, nonmovable=True)
+            return rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
+        return fn
+
+    def test_instantiate_nonmovable(self):
+        res = self.runner('instantiate_nonmovable')
+        assert res([]) == 0
+
+
 class TestIncrementalMiniMarkGC(TestMiniMarkGC):
     gcname = "incminimark"
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to