Commits

Armin Rigo  committed b451f9d

Use jit.conditional_call() also in ll_build()

  • Participants
  • Parent commits ce60e2f
  • Branches stringbuilder2-perf

Comments (0)

Files changed (3)

File rpython/jit/metainterp/blackhole.py

         if condition:
             cpu.bh_call_v(func, args_i, None, None, calldescr)
 
+    @arguments("cpu", "i", "i", "R", "d")
+    def bhimpl_conditional_call_r_v(cpu, condition, func, args_r, calldescr):
+        if condition:
+            cpu.bh_call_v(func, None, args_r, None, calldescr)
+
     @arguments("cpu", "i", "i", "I", "R", "d")
     def bhimpl_conditional_call_ir_v(cpu, condition, func, args_i, args_r,
                                      calldescr):

File rpython/jit/metainterp/pyjitpl.py

                                     pc):
         self.do_conditional_call(condbox, funcbox, argboxes, calldescr, pc)
 
+    opimpl_conditional_call_r_v = opimpl_conditional_call_i_v
+
     @arguments("box", "box", "boxes2", "descr", "orgpc")
     def opimpl_conditional_call_ir_v(self, condbox, funcbox, argboxes,
                                      calldescr, pc):

File rpython/rtyper/lltypesystem/rbuilder.py

         '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),
+        'mallocfn': staticAdtMethod(rstr.mallocstr),
     }
 )
 
         '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),
+        'mallocfn': staticAdtMethod(rstr.mallocunicode),
     }
 )
 
             ll_builder.current_end - ll_builder.current_pos)
         return ll_builder.total_size - num_chars_missing_from_last_piece
 
-    @classmethod
-    def ll_build(cls, ll_builder):
-        if not ll_builder.extra_pieces:
-            # fast-path: the result fits in a single buf.
-            final_size = ll_builder.current_pos
-            buf = ll_builder.current_buf
-            if ll_builder.total_size != final_size:
-                ll_assert(final_size < ll_builder.total_size,
-                          "final_size > ll_builder.total_size?")
-                buf = rgc.ll_shrink_array(buf, final_size)
-                ll_builder.current_buf = buf
-                ll_builder.current_end = final_size
-                ll_builder.total_size = final_size
-            return buf
-        else:
-            return BaseStringBuilderRepr._ll_build_extra(cls, ll_builder)
+    @staticmethod
+    def ll_build(ll_builder):
+        jit.conditional_call(bool(ll_builder.extra_pieces),
+                             BaseStringBuilderRepr._ll_fold_pieces, ll_builder)
+        # Here is the one remaining "unexpected" branch with the JIT.
+        # Too bad, but it seems it's the only reasonable way to support
+        # both virtual builders and avoid-shrink-if-size-doesn't-change
+        final_size = ll_builder.current_pos
+        if final_size != ll_builder.total_size:
+            BaseStringBuilderRepr._ll_shrink_final(ll_builder)
+        return ll_builder.current_buf
 
     @staticmethod
-    @jit.dont_look_inside
-    def _ll_build_extra(cls, ll_builder):
-        final_size = cls.ll_getlength(ll_builder)
+    def _ll_shrink_final(ll_builder):
+        final_size = ll_builder.current_pos
+        ll_assert(final_size <= ll_builder.total_size,
+                  "final_size > ll_builder.total_size?")
+        buf = rgc.ll_shrink_array(ll_builder.current_buf, final_size)
+        ll_builder.current_buf = buf
+        ll_builder.current_end = final_size
+        ll_builder.total_size = final_size
+
+    @staticmethod
+    def _ll_fold_pieces(ll_builder):
+        final_size = BaseStringBuilderRepr.ll_getlength(ll_builder)
         ll_assert(final_size >= 0, "negative final_size")
         extra = ll_builder.extra_pieces
         ll_builder.extra_pieces = lltype.nullptr(lltype.typeOf(extra).TO)
         #
-        result = cls.mallocfn(final_size)
+        result = ll_builder.mallocfn(final_size)
         piece = ll_builder.current_buf
         piece_lgt = ll_builder.current_pos
         ll_assert(ll_builder.current_end == len(piece.chars),
             piece_lgt = len(piece.chars)
             extra = extra.prev_piece
         ll_assert(dst == 0, "rbuilder build: underflow")
-        return result
 
     @classmethod
     def ll_bool(cls, ll_builder):