Author: Alex Gaynor <[email protected]>
Branch: 
Changeset: r64493:f6e4e1ccc876
Date: 2013-05-22 15:49 -0700
http://bitbucket.org/pypy/pypy/changeset/f6e4e1ccc876/

Log:    When ll_shrink_array is called a constant string allow that to be
        propogated.

diff --git a/rpython/jit/codewriter/effectinfo.py 
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -21,6 +21,7 @@
     OS_NONE                     = 0    # normal case, no oopspec
     OS_ARRAYCOPY                = 1    # "list.ll_arraycopy"
     OS_STR2UNICODE              = 2    # "str.str2unicode"
+    OS_SHRINK_ARRAY             = 3    # rgc.ll_shrink_array
     #
     OS_STR_CONCAT               = 22   # "stroruni.concat"
     OS_STR_SLICE                = 23   # "stroruni.slice"
@@ -82,8 +83,10 @@
     OS_JIT_FORCE_VIRTUAL        = 120
 
     # for debugging:
-    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
-                        OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL])
+    _OS_CANRAISE = set([
+        OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR,
+        OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY,
+    ])
 
     def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
                 write_descrs_fields, write_descrs_arrays,
diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -398,6 +398,8 @@
             prepare = self._handle_libffi_call
         elif oopspec_name.startswith('math.sqrt'):
             prepare = self._handle_math_sqrt_call
+        elif oopspec_name.startswith('rgc.'):
+            prepare = self._handle_rgc_call
         else:
             prepare = self.prepare_builtin_call
         try:
@@ -1779,6 +1781,12 @@
         return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
                                          EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
 
+    def _handle_rgc_call(self, op, oopspec_name, args):
+        if oopspec_name == 'rgc.ll_shrink_array':
+            return self._handle_oopspec_call(op, args, 
EffectInfo.OS_SHRINK_ARRAY, EffectInfo.EF_CAN_RAISE)
+        else:
+            raise NotImplementedError(oopspec_name)
+
     def rewrite_op_jit_force_quasi_immutable(self, op):
         v_inst, c_fieldname = op.args
         descr1 = self.cpu.fielddescrof(v_inst.concretetype.TO,
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py 
b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -136,6 +136,9 @@
         assert size <= MAX_CONST_LEN
         self._chars = [None] * size
 
+    def shrink(self, length):
+        del self._chars[length:]
+
     def setup_slice(self, longerlist, start, stop):
         assert 0 <= start <= stop <= len(longerlist)
         self._chars = longerlist[start:stop]
@@ -554,6 +557,9 @@
             if oopspecindex == EffectInfo.OS_STR2UNICODE:
                 if self.opt_call_str_STR2UNICODE(op):
                     return
+            if oopspecindex == EffectInfo.OS_SHRINK_ARRAY:
+                if self.opt_call_SHRINK_ARRAY(op):
+                    return
         self.emit_operation(op)
 
     optimize_CALL_PURE = optimize_CALL
@@ -721,6 +727,19 @@
             return True
         return False
 
+    def opt_call_SHRINK_ARRAY(self, op):
+        v1 = self.getvalue(op.getarg(1))
+        v2 = self.getvalue(op.getarg(2))
+        # If the index is constant, if the argument is virtual (we only support
+        # VStringPlainValue for now) we can optimize away the call.
+        if v2.is_constant() and v1.is_virtual() and isinstance(v1, 
VStringPlainValue):
+            length = v2.box.getint()
+            v1.shrink(length)
+            self.last_emitted_operation = REMOVED
+            self.make_equal_to(op.result, v1)
+            return True
+        return False
+
     def generate_modified_call(self, oopspecindex, args, result, mode):
         oopspecindex += mode.OS_offset
         cic = self.optimizer.metainterp_sd.callinfocollection
diff --git a/rpython/jit/metainterp/test/test_string.py 
b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -582,6 +582,26 @@
         res = self.interp_operations(f, [13])
         assert res == 13
 
+    def test_shrink_array(self):
+        jitdriver = JitDriver(reds=['result', 'n'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def f(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(20)
+                b.append(_str("Testing!"))
+                result += len(b.build())
+                n -= 1
+            return result
+
+        res = self.meta_interp(f, [9])
+        assert res == f(9)
+        self.check_resops({
+            'jump': 1, 'guard_true': 2, 'int_ge': 2, 'int_add': 2, 'int_sub': 2
+        })
+
 
 #class TestOOtype(StringTests, OOJitMixin):
 #    CALL = "oosend"
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -183,6 +183,7 @@
             return True
     return False
 
+
 @jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start, 
length)')
 @enforceargs(None, None, int, int, int)
 @specialize.ll()
@@ -229,6 +230,9 @@
     keepalive_until_here(source)
     keepalive_until_here(dest)
 
+
[email protected]('rgc.ll_shrink_array(p, smallerlength)')
[email protected]()
 def ll_shrink_array(p, smallerlength):
     from rpython.rtyper.lltypesystem.lloperation import llop
     from rpython.rlib.objectmodel import keepalive_until_here
@@ -249,16 +253,15 @@
     ARRAY = getattr(TP, TP._arrayfld)
     offset = (llmemory.offsetof(TP, TP._arrayfld) +
               llmemory.itemoffsetof(ARRAY, 0))
-    source_addr = llmemory.cast_ptr_to_adr(p)    + offset
-    dest_addr   = llmemory.cast_ptr_to_adr(newp) + offset
+    source_addr = llmemory.cast_ptr_to_adr(p) + offset
+    dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
     llmemory.raw_memcopy(source_addr, dest_addr,
                          llmemory.sizeof(ARRAY.OF) * smallerlength)
 
     keepalive_until_here(p)
     keepalive_until_here(newp)
     return newp
-ll_shrink_array._annspecialcase_ = 'specialize:ll'
-ll_shrink_array._jit_look_inside_ = False
+
 
 def no_collect(func):
     func._dont_inline_ = True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to