Author: Armin Rigo <[email protected]>
Branch: stringbuilder2-perf
Changeset: r72055:46acbdfc4837
Date: 2014-06-15 12:36 +0200
http://bitbucket.org/pypy/pypy/changeset/46acbdfc4837/

Log:    ll_append_char_2.

diff --git a/rpython/rtyper/lltypesystem/rbuilder.py 
b/rpython/rtyper/lltypesystem/rbuilder.py
--- a/rpython/rtyper/lltypesystem/rbuilder.py
+++ b/rpython/rtyper/lltypesystem/rbuilder.py
@@ -1,6 +1,6 @@
 from rpython.rlib import rgc, jit
 from rpython.rlib.objectmodel import enforceargs, specialize
-from rpython.rlib.rarithmetic import ovfcheck, r_uint
+from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rlib.debug import ll_assert
 from rpython.rtyper.rptr import PtrRepr
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
@@ -80,9 +80,19 @@
         ll_builder.skip += part1
         stringbuilder_grow(ll_builder, size - part1)
 
+    def stringbuilder_append_overflow_2(ll_builder, char0):
+        # Overflow when writing two chars.  There are two cases depending
+        # on whether one char still fits or not.
+        if ll_builder.current_pos < ll_builder.current_end:
+            ll_builder.current_buf.chars[ll_builder.current_pos] = char0
+            ll_builder.skip = 1
+        stringbuilder_grow(ll_builder, 2)
+
     return (func_with_new_name(stringbuilder_grow, '%s_grow' % name),
             func_with_new_name(stringbuilder_append_overflow,
-                               '%s_append_overflow' % name))
+                               '%s_append_overflow' % name),
+            func_with_new_name(stringbuilder_append_overflow_2,
+                               '%s_append_overflow_2' % name))
 
 stringbuilder_grows = new_grow_funcs('stringbuilder', rstr.mallocstr)
 unicodebuilder_grows = new_grow_funcs('unicodebuilder', rstr.mallocunicode)
@@ -102,6 +112,7 @@
     adtmeths={
         'grow': staticAdtMethod(stringbuilder_grows[0]),
         'append_overflow': staticAdtMethod(stringbuilder_grows[1]),
+        'append_overflow_2': staticAdtMethod(stringbuilder_grows[2]),
         'copy_string_contents': staticAdtMethod(rstr.copy_string_contents),
         'copy_raw_to_string': staticAdtMethod(rstr.copy_raw_to_string),
     }
@@ -122,6 +133,7 @@
     adtmeths={
         'grow': staticAdtMethod(unicodebuilder_grows[0]),
         'append_overflow': staticAdtMethod(unicodebuilder_grows[1]),
+        'append_overflow_2': staticAdtMethod(unicodebuilder_grows[2]),
         'copy_string_contents': staticAdtMethod(rstr.copy_unicode_contents),
         'copy_raw_to_string': staticAdtMethod(rstr.copy_raw_to_unicode),
     }
@@ -169,40 +181,20 @@
 
     @staticmethod
     def ll_append_char_2(ll_builder, char0, char1):
-        if jit.we_are_jitted():
-            BaseStringBuilderRepr._ll_jit_append_char_2(ll_builder, 
char0,char1)
-        else:
-            BaseStringBuilderRepr._ll_append_char_2(ll_builder, char0, char1)
-
-    @staticmethod
-    @jit.dont_look_inside
-    def _ll_append_char_2(ll_builder, char0, char1):
-        ofs = ll_builder.current_ofs
-        end = ofs + 2 * ll_builder.charsize
-        if uint_gt(end, ll_builder.current_end):
-            BaseStringBuilderRepr._ll_append_char(ll_builder, char0)
-            BaseStringBuilderRepr._ll_append_char(ll_builder, char1)
-            return
-        ll_builder.current_ofs = end
-        # --- no GC! ---
-        raw = rffi.cast(rffi.CCHARP, ll_builder.current_buf)
-        ll_rawsetitem(raw, ofs, char0)
-        ll_rawsetitem(raw, ofs + ll_builder.charsize, char1)
-        # --- end ---
-
-    @staticmethod
-    def _ll_jit_append_char_2(ll_builder, char0, char1):
-        ofs = ll_builder.current_ofs
-        end = ofs + 2 * ll_builder.charsize
-        if bool(ll_builder.current_buf) and uint_le(end,
-                                                    ll_builder.current_end):
-            ll_builder.current_ofs = end
-            buf = ll_builder.current_buf
-            index = (ofs - ll_baseofs(buf)) // ll_builder.charsize
-            buf.chars[index] = char0
-            buf.chars[index + 1] = char1
-            return
-        BaseStringBuilderRepr._ll_append_char_2(ll_builder, char0, char1)
+        ll_builder.skip = 2
+        jit.conditional_call(
+            ll_builder.current_end - ll_builder.current_pos < 2,
+            ll_builder.append_overflow_2, ll_builder, char0)
+        pos = ll_builder.current_pos
+        buf = ll_builder.current_buf
+        buf.chars[pos] = char0
+        pos += ll_builder.skip
+        ll_builder.current_pos = pos
+        buf.chars[pos - 1] = char1
+        # NB. this usually writes into buf.chars[current_pos] and
+        # buf.chars[current_pos+1], except if we had an overflow right
+        # in the middle of the two chars.  In that case, 'skip' is set to
+        # 1 and only one char is written: the 'char1' overrides the 'char0'.
 
     @staticmethod
     @always_inline
@@ -210,7 +202,7 @@
         size = end - start
         if jit.we_are_jitted():
             if BaseStringBuilderRepr._ll_jit_try_append_slice(
-                    ll_builder, ll_str, size):
+                    ll_builder, ll_str, start, size):
                 return
         ll_builder.skip = start
         jit.conditional_call(
@@ -224,7 +216,7 @@
         ll_builder.current_pos = pos + size
 
     @staticmethod
-    def _ll_jit_try_append_slice(ll_builder, ll_str, size):
+    def _ll_jit_try_append_slice(ll_builder, ll_str, start, size):
         if jit.isconstant(size):
             if size == 0:
                 return True
@@ -237,18 +229,6 @@
                                                        ll_str.chars[start],
                                                        ll_str.chars[start + 1])
                 return True
-        if bool(ll_builder.current_buf):
-            ofs = ll_builder.current_ofs
-            end = ofs + size * ll_builder.charsize
-            if uint_le(end, ll_builder.current_end):
-                ll_builder.current_ofs = end
-                buf = ll_builder.current_buf
-                index = (ofs - ll_baseofs(buf)) // ll_builder.charsize
-                if lltype.typeOf(buf).TO.chars.OF == lltype.Char:
-                    rstr.copy_string_contents(ll_str, buf, start, index, size)
-                else:
-                    rstr.copy_unicode_contents(ll_str, buf, start, index, size)
-                return True
         return False     # use the fall-back path
 
     @staticmethod
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to