[pypy-commit] pypy op_malloc_gc: In-progress.

arigo noreply at buildbot.pypy.org
Sat Dec 17 18:52:28 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: op_malloc_gc
Changeset: r50626:fc4c51ca1ec4
Date: 2011-12-17 15:57 +0100
http://bitbucket.org/pypy/pypy/changeset/fc4c51ca1ec4/

Log:	In-progress.

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -41,15 +41,21 @@
         self.field_strlen_descr = get_field_arraylen_descr(self, rstr.STR)
         self.field_unicodelen_descr = get_field_arraylen_descr(self,
                                                                rstr.UNICODE)
+        self._generated_functions = []
 
-    def _ready(self):
-        MALLOC_FIXEDSIZE = lltype.Ptr(
-            lltype.FuncType([lltype.Signed], llmemory.GCREF))
-        self.malloc_fixedsize_fn = llhelper(MALLOC_FIXEDSIZE,
-                                            self.malloc_fixedsize)
-        self.c_malloc_fixedsize_fn = ConstInt(
-            heaptracker.adr2int(llmemory.cast_ptr_to_adr(
-                self.malloc_fixedsize_fn)))
+    def generate_function(self, funcname, func, ARGS, RESULT=llmemory.GCREF):
+        """Generates a variant of malloc with the given name and the given
+        arguments.  It should raise MemoryError and return NULL if out of
+        memory.
+        """
+        FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, RESULT))
+        ll_func = llhelper(FUNCPTR, func)
+        c_ll_func = ConstInt(
+            heaptracker.adr2int(llmemory.cast_ptr_to_adr(ll_func)))
+        setattr(self, '%s'      % funcname, func)
+        setattr(self, '%s_fn'   % funcname, ll_func)
+        setattr(self, 'c_%s_fn' % funcname, c_ll_func)
+        self._generated_functions.append(funcname)
 
     def _freeze_(self):
         return True
@@ -168,9 +174,8 @@
             if not res:
                 raise MemoryError
             return res
-        self.malloc_fixedsize = malloc_fixedsize
-        #
-        self._ready()
+        self.generate_function('malloc_fixedsize', malloc_fixedsize,
+                               [lltype.Signed])
 
     def _gc_malloc(self, size, tid):
         # Boehm: 'tid' is ignored
@@ -618,7 +623,7 @@
             self._make_gcrootmap()
             self._make_layoutbuilder()
             self._setup_gcclass()
-            self._make_functions()
+        self._make_functions()
 
     def _initialize_for_tests(self):
         self.layoutbuilder = None
@@ -673,37 +678,49 @@
 
     def _make_functions(self):
         llop1 = self.llop1
-        # make the fixed malloc function, with one argument
-        def malloc_gc_fixed(size):
+
+        def malloc_nursery(size):
+            """Allocate 'size' null bytes out of the nursery.
+            Note that the fast path is typically inlined by the backend.
+            """
             type_id = rffi.cast(llgroup.HALFWORD, 0)    # missing here
-            res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
-                                                  type_id, size,
-                                                  False, False, False)
-            #llop.debug_print(lltype.Void, "\tmalloc_basic", size, "-->", res)
-            # In case the operation above failed, we are returning NULL
-            # from this function to assembler.  There is also an RPython
-            # exception set, typically MemoryError; but it's easier and
-            # faster to check for the NULL return value, as done by
-            # translator/exceptiontransform.py.
-            return res
-        self.malloc_gc_fixed = malloc_gc_fixed
-        self.MALLOC_GC_FIXED = lltype.Ptr(
-            lltype.FuncType([lltype.Signed], llmemory.GCREF))
-        #
-        # make the varsize malloc function, with three arguments
-        def malloc_gc_variable(basesize, num_elem, itemsize):
-            xx
-        self.malloc_gc_variable = malloc_gc_variable
-        self.MALLOC_GC_VARIABLE = lltype.Ptr(
-            lltype.FuncType([lltype.Signed] * 3, llmemory.GCREF))
-        #
-        self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
-            [llmemory.Address, llmemory.Address], lltype.Void))
-        self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
-            [llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
-        self.write_barrier_descr = WriteBarrierDescr(self)
-        self.fielddescr_tid = self.write_barrier_descr.fielddescr_tid
-        #
+            return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+                                                   type_id, size,
+                                                   False, False, False)
+        self.generate_function('malloc_nursery', malloc_nursery,
+                               [lltype.Signed])
+
+##        # make the fixed malloc function, with one argument
+##        def malloc_gc_fixed(size):
+##            type_id = rffi.cast(llgroup.HALFWORD, 0)    # missing here
+##            res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+##                                                  type_id, size,
+##                                                  False, False, False)
+##            #llop.debug_print(lltype.Void, "\tmalloc_basic", size, "-->", res)
+##            # In case the operation above failed, we are returning NULL
+##            # from this function to assembler.  There is also an RPython
+##            # exception set, typically MemoryError; but it's easier and
+##            # faster to check for the NULL return value, as done by
+##            # translator/exceptiontransform.py.
+##            return res
+##        self.malloc_gc_fixed = malloc_gc_fixed
+##        self.MALLOC_GC_FIXED = lltype.Ptr(
+##            lltype.FuncType([lltype.Signed], llmemory.GCREF))
+##        #
+##        # make the varsize malloc function, with three arguments
+##        def malloc_gc_variable(basesize, num_elem, itemsize):
+##            xx
+##        self.malloc_gc_variable = malloc_gc_variable
+##        self.MALLOC_GC_VARIABLE = lltype.Ptr(
+##            lltype.FuncType([lltype.Signed] * 3, llmemory.GCREF))
+##        #
+##        self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+##            [llmemory.Address, llmemory.Address], lltype.Void))
+##        self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
+##            [llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
+##        self.write_barrier_descr = WriteBarrierDescr(self)
+##        self.fielddescr_tid = self.write_barrier_descr.fielddescr_tid
+##        #
 ##        def malloc_array(itemsize, tid, num_elem):
 ##            type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
 ##            check_typeid(type_id)
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -153,8 +153,8 @@
         self.recent_mallocs[v_result] = None
 
     def gen_malloc_nursery(self, size, v_result):
-        """Try to generate or update a MALLOC_NURSERY.
-        If that fails, generate a plain MALLOC_GC instead.
+        """Try to generate or update a CALL_MALLOC_NURSERY.
+        If that fails, generate a plain CALL_MALLOC_GC instead.
         """
         if not self.gc_ll_descr.can_use_nursery_malloc(size):
             return self.gen_malloc_fixedsize(size, v_result)
@@ -164,11 +164,11 @@
         #
         if self._op_malloc_nursery is not None:
             # already a MALLOC_NURSERY: increment its total size
-            total_size = self._op_malloc_nursery.getarg(0).getint()
+            total_size = self._op_malloc_nursery.getarg(1).getint()
             total_size += size
             if self.gc_ll_descr.can_use_nursery_malloc(total_size):
                 # if the total size is still reasonable, merge it
-                self._op_malloc_nursery.setarg(0, ConstInt(total_size))
+                self._op_malloc_nursery.setarg(1, ConstInt(total_size))
                 op = ResOperation(rop.INT_ADD,
                                   [self._v_last_malloced_nursery,
                                    ConstInt(self._previous_size)],
@@ -176,7 +176,10 @@
         if op is None:
             # if we failed to merge with a previous MALLOC_NURSERY, emit one
             self.emitting_an_operation_that_can_collect()
-            op = ResOperation(rop.MALLOC_NURSERY, [ConstInt(size)], v_result)
+            op = ResOperation(rop.CALL_MALLOC_NURSERY,
+                              [self.gc_ll_descr.c_malloc_nursery_fn,
+                               ConstInt(size)],
+                              v_result)
             self._op_malloc_nursery = op
         #
         self.newops.append(op)
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -15,8 +15,6 @@
 
 class RewriteTests(object):
     def check_rewrite(self, frm_operations, to_operations):
-        malloc_fixedsize = self.gc_ll_descr.malloc_fixedsize_fn
-        #
         S = lltype.GcStruct('S', ('x', lltype.Signed),
                                  ('y', lltype.Signed))
         sdescr = get_size_descr(self.gc_ll_descr, S)
@@ -62,9 +60,14 @@
         unicodelendescr = get_field_arraylen_descr(self.gc_ll_descr,
                                                    rstr.UNICODE)
         #
-        ops = parse(frm_operations, namespace=locals())
-        expected = parse(to_operations % Evaluator(locals()),
-                         namespace=locals())
+        namespace = locals().copy()
+        #
+        for funcname in self.gc_ll_descr._generated_functions:
+            namespace[funcname] = getattr(self.gc_ll_descr, '%s_fn' % funcname)
+        #
+        ops = parse(frm_operations, namespace=namespace)
+        expected = parse(to_operations % Evaluator(namespace),
+                         namespace=namespace)
         operations = self.gc_ll_descr.rewrite_assembler(self.cpu,
                                                         ops.operations,
                                                         [])
@@ -195,7 +198,8 @@
             jump()
         """, """
             [p1]
-            p0 = malloc_nursery(%(sdescr.size)d)
+            p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+                                     %(sdescr.size)d)
             setfield_gc(p0, 1234, descr=tiddescr)
             jump()
         """)
@@ -209,7 +213,8 @@
             jump()
         """, """
             []
-            p0 = malloc_nursery(%(sdescr.size + tdescr.size + sdescr.size)d)
+            p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+                               %(sdescr.size + tdescr.size + sdescr.size)d)
             setfield_gc(p0, 1234, descr=tiddescr)
             p1 = int_add(p0, %(sdescr.size)d)
             setfield_gc(p1, 5678, descr=tiddescr)


More information about the pypy-commit mailing list