[pypy-commit] pypy fast-newarray: rewrite for str and unicode

fijal noreply at buildbot.pypy.org
Mon Apr 15 23:04:17 CEST 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: fast-newarray
Changeset: r63391:c89be8d76c1e
Date: 2013-04-15 22:40 +0200
http://bitbucket.org/pypy/pypy/changeset/c89be8d76c1e/

Log:	rewrite for str and unicode

diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -8,6 +8,10 @@
 from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
 from rpython.jit.metainterp.history import JitCellToken
 
+FLAG_ARRAY = 0
+FLAG_STR = 1
+FLAG_UNICODE = 2
+
 class GcRewriterAssembler(object):
     """ This class performs the following rewrites on the list of operations:
 
@@ -299,15 +303,28 @@
                                    arraydescr):
         """ itemsize is an int, v_length and v_result are boxes
         """
-        if (arraydescr.basesize != self.gc_ll_descr.standard_array_basesize
-            or arraydescr.lendescr.offset !=
-            self.gc_ll_descr.standard_array_length_ofs):
+        gc_descr = self.gc_ll_descr
+        str_descr = gc_descr.str_descr
+        unicode_descr = gc_descr.unicode_descr
+        if (arraydescr.basesize == gc_descr.standard_array_basesize and
+            arraydescr.lendescr.offset == gc_descr.standard_array_length_ofs):
+            flag = FLAG_ARRAY # standard array
+        elif (arraydescr.basesize == str_descr.basesize and
+              arraydescr.lendescr.offset == str_descr.lendescr.offset):
+            flag = FLAG_STR
+        elif (arraydescr.basesize == unicode_descr.basesize and
+              arraydescr.lendescr.offset == unicode_descr.lendescr.offset):
+            # note that this might never be reached if we have the same
+            # offsets, that does not quite matter though
+            flag = FLAG_UNICODE
+        else:
             return False
         self.emitting_an_operation_that_can_collect()
         op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE,
-                          [ConstInt(itemsize), v_length],
+                          [ConstInt(flag), ConstInt(itemsize), v_length],
                           v_result, descr=arraydescr)
         self.newops.append(op)
+        self.recent_mallocs[v_result] = None
         return True
 
     def gen_malloc_nursery_varsize_small(self, sizebox, v_result):
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -408,11 +408,23 @@
             jump(i0)
         """, """
             [i0]
-            p0 = call_malloc_nursery_varsize(1, i0, descr=bdescr)
+            p0 = call_malloc_nursery_varsize(0, 1, i0, descr=bdescr)
             setfield_gc(p0, i0, descr=blendescr)
             jump(i0)
         """)
 
+    def test_rewrite_new_string(self):
+        self.check_rewrite("""
+        [i0]
+        p0 = newstr(i0)
+        jump(i0)
+        """, """
+        [i0]
+        p0 = call_malloc_nursery_varsize(1, 1, i0, descr=strdescr)
+        setfield_gc(p0, i0, descr=strlendescr)
+        jump(i0)
+        """)
+
     def test_rewrite_assembler_nonstandard_array(self):
         # a non-standard array is a bit hard to get; e.g. GcArray(Float)
         # is like that on Win32, but not on Linux.  Build one manually...
@@ -533,10 +545,12 @@
             p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
             setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
             setfield_gc(p1, 10, descr=unicodelendescr)
-            p2 = call_malloc_gc(ConstClass(malloc_unicode), i2, \
-                                descr=malloc_unicode_descr)
-            p3 = call_malloc_gc(ConstClass(malloc_str), i2, \
-                                descr=malloc_str_descr)
+            p2 = call_malloc_nursery_varsize(1, 4, i2, \
+                                descr=unicodedescr)
+            setfield_gc(p2, i2, descr=unicodelendescr)
+            p3 = call_malloc_nursery_varsize(1, 1, i2, \
+                                descr=strdescr)
+            setfield_gc(p3, i2, descr=strlendescr)
             jump()
         """)
 
@@ -716,8 +730,9 @@
             [i0]
             p0 = call_malloc_nursery(%(tdescr.size)d)
             setfield_gc(p0, 5678, descr=tiddescr)
-            p1 = call_malloc_gc(ConstClass(malloc_str), i0, \
-                                descr=malloc_str_descr)
+            p1 = call_malloc_nursery_varsize(1, 1, i0, \
+                                descr=strdescr)
+            setfield_gc(p1, i0, descr=strlendescr)
             cond_call_gc_wb(p0, p1, descr=wbdescr)
             setfield_raw(p0, p1, descr=tzdescr)
             jump()
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -525,7 +525,7 @@
     'CALL_PURE/*d',             # removed before it's passed to the backend
     'CALL_MALLOC_GC/*d',      # like CALL, but NULL => propagate MemoryError
     'CALL_MALLOC_NURSERY/1',  # nursery malloc, const number of bytes, zeroed
-    'CALL_MALLOC_NURSERY_VARSIZE/2d',
+    'CALL_MALLOC_NURSERY_VARSIZE/3d',
     'CALL_MALLOC_NURSERY_VARSIZE_SMALL/1',
     # nursery malloc, non-const number of bytes, zeroed
     # note that the number of bytes must be well known to be small enough


More information about the pypy-commit mailing list