[pypy-commit] pypy op_malloc_gc: newstr, newunicode.

arigo noreply at buildbot.pypy.org
Sat Nov 26 13:49:10 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: op_malloc_gc
Changeset: r49816:ded0faf183e2
Date: 2011-11-26 13:48 +0100
http://bitbucket.org/pypy/pypy/changeset/ded0faf183e2/

Log:	newstr, newunicode.

diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -149,16 +149,28 @@
         cachedict[fieldname] = fielddescr
         return fielddescr
 
-def get_field_arraylen_descr(gccache, ARRAY):
+def get_field_arraylen_descr(gccache, ARRAY_OR_STRUCT):
     cache = gccache._cache_arraylen
+    if isinstance(ARRAY_OR_STRUCT, lltype.GcArray):
+        # assume that they all have the length at the same offset
+        key = 'array'
+    else:
+        # assume that it is STR or UNICODE
+        assert isinstance(ARRAY_OR_STRUCT.chars, lltype.Array)
+        key = ARRAY_OR_STRUCT
     try:
-        return cache[ARRAY]
+        return cache[key]
     except KeyError:
         tsc = gccache.translate_support_code
-        (_, _, ofs) = symbolic.get_array_token(ARRAY, tsc)
+        (_, _, ofs) = symbolic.get_array_token(ARRAY_OR_STRUCT, tsc)
+        if key == 'array' and tsc:
+            (_, _, baseofs) = symbolic.get_array_token(_A, tsc)
+            assert baseofs == ofs, ("arrays %r and %r don't have the length "
+                                    "field at the same offset!" %
+                                    (ARRAY_OR_STRUCT, _A))
         SignedFieldDescr = getFieldDescrClass(lltype.Signed)
         result = SignedFieldDescr("len", ofs)
-        cache[ARRAY] = result
+        cache[key] = result
         return result
 
 # ____________________________________________________________
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
@@ -36,6 +36,14 @@
         else:
             self.fielddescr_vtable = get_field_descr(self, rclass.OBJECT,
                                                      'typeptr')
+        (self.str_basesize, self.str_itemsize, self.str_ofs_length
+         ) = symbolic.get_array_token(rstr.STR, self.translate_support_code)
+        (self.unicode_basesize, self.unicode_itemsize, self.unicode_ofs_length
+         ) = symbolic.get_array_token(rstr.UNICODE,self.translate_support_code)
+        self.field_strlen_descr = get_field_arraylen_descr(self, rstr.STR)
+        self.field_unicodelen_descr = get_field_arraylen_descr(self,
+                                                               rstr.UNICODE)
+
     def _freeze_(self):
         return True
     def initialize(self):
@@ -134,10 +142,6 @@
             [lltype.Signed] * 4, llmemory.GCREF))
 
 
-        (str_basesize, str_itemsize, str_ofs_length
-         ) = symbolic.get_array_token(rstr.STR, self.translate_support_code)
-        (unicode_basesize, unicode_itemsize, unicode_ofs_length
-         ) = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code)
         def malloc_str(length):
             return self.malloc_array(
                 str_basesize, str_itemsize, str_ofs_length, length
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
@@ -82,21 +82,34 @@
         elif opnum == rop.NEW_ARRAY:
             descr = op.getdescr()
             assert isinstance(descr, BaseArrayDescr)
-            #...
-            c_basesize = ConstInt(descr.get_base_size(self.tsc))
-            c_itemsize = ConstInt(descr.get_item_size(self.tsc))
-            v_length = op.getarg(0)
-            op = ResOperation(rop.MALLOC_GC, [c_basesize,
-                                              v_length,
-                                              c_itemsize],
-                              op.result)
-            self.newops.append(op)
-            op = ResOperation(rop.SETFIELD_GC, [op.result, v_length],
-                              None, descr=descr.field_arraylen_descr)
-            self.newops.append(op)
+            self.handle_new_array(descr.get_base_size(self.tsc),
+                                  descr.get_item_size(self.tsc),
+                                  descr.field_arraylen_descr,
+                                  op)
+        elif opnum == rop.NEWSTR:
+            self.handle_new_array(self.gc_ll_descr.str_basesize,
+                                  self.gc_ll_descr.str_itemsize,
+                                  self.gc_ll_descr.field_strlen_descr,
+                                  op)
+        elif opnum == rop.NEWUNICODE:
+            self.handle_new_array(self.gc_ll_descr.unicode_basesize,
+                                  self.gc_ll_descr.unicode_itemsize,
+                                  self.gc_ll_descr.field_unicodelen_descr,
+                                  op)
         else:
             raise NotImplementedError(op.getopname())
 
+    def handle_new_array(self, base_size, item_size, arraylen_descr, op):
+        v_length = op.getarg(0)
+        op = ResOperation(rop.MALLOC_GC, [ConstInt(base_size),
+                                          v_length,
+                                          ConstInt(item_size)],
+                          op.result)
+        self.newops.append(op)
+        op = ResOperation(rop.SETFIELD_GC, [op.result, v_length],
+                          None, descr=arraylen_descr)
+        self.newops.append(op)
+
 ##                if op.getopnum() == rop.NEW:
 ##                    descr = op.getdescr()
 ##                    assert isinstance(descr, BaseSizeDescr)
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
@@ -54,6 +54,15 @@
                 pass
             WORD = globals()['WORD']
             #
+            str_basesize = self.gc_ll_descr.str_basesize
+            str_itemsize = self.gc_ll_descr.str_itemsize
+            strlendescr = get_field_arraylen_descr(self.gc_ll_descr, rstr.STR)
+            #
+            unicode_basesize = self.gc_ll_descr.unicode_basesize
+            unicode_itemsize = self.gc_ll_descr.unicode_itemsize
+            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())
@@ -147,6 +156,18 @@
             jump()
         """)
 
+    def test_newunicode(self):
+        self.check_rewrite("""
+            [i1]
+            p0 = newunicode(10)
+            jump()
+        """, """
+            [i1]
+            p0 = malloc_gc(%(unicode_basesize)d, 10, %(unicode_itemsize)d)
+            setfield_gc(p0, 10, descr=unicodelendescr)
+            jump()
+        """)
+
 
 class TestFramework(RewriteTests):
     def setup_method(self, meth):


More information about the pypy-commit mailing list