Author: Armin Rigo <[email protected]>
Branch: improve-vmprof-testing
Changeset: r86053:2de09f51a345
Date: 2016-08-07 10:46 +0200
http://bitbucket.org/pypy/pypy/changeset/2de09f51a345/

Log:    in-progress

diff --git a/rpython/jit/backend/test/test_rvmprof.py 
b/rpython/jit/backend/test/test_rvmprof.py
--- a/rpython/jit/backend/test/test_rvmprof.py
+++ b/rpython/jit/backend/test/test_rvmprof.py
@@ -55,7 +55,6 @@
                 driver.jit_merge_point(code=code, c=c, i=i, codes=codes, n=n)
                 if code.name == "main":
                     c = f(codes, codes[1], 1, c)
-                    driver.can_enter_jit(code=code, c=c, i=i, codes=codes, n=n)
                 else:
                     llfn()
                     c -= 1
@@ -74,6 +73,46 @@
         assert visited[:3] == [[(1, 12), (1, 8)], [(1, 12), (1, 8)], [(1, 12), 
(1, 8)]]
 
 
+    def test_leaving_with_exception(self):
+        visited, llfn, CodeObj, get_code_fn, get_name = self.misc
+        driver = jit.JitDriver(greens=['code'], reds=['c', 'i', 'n', 'codes'])
+
+        class MyExc(Exception):
+            def __init__(self, c):
+                self.c = c
+
+        @vmprof_execute_code("main", get_code_fn,
+                             _hack_update_stack_untranslated=True)
+        def f(codes, code, n, c):
+            i = 0
+            while i < n:
+                driver.jit_merge_point(code=code, c=c, i=i, codes=codes, n=n)
+                if code.name == "main":
+                    try:
+                        f(codes, codes[1], 1, c)
+                    except MyExc as e:
+                        c = e.c
+                else:
+                    llfn()
+                    c -= 1
+                i += 1
+            raise MyExc(c)
+
+        def main(n):
+            codes = [CodeObj("main"), CodeObj("not main")]
+            for code in codes:
+                register_code(code, get_name)
+            try:
+                f(codes, codes[0], n, 8)
+            except MyExc as e:
+                return e.c
+
+        null = lltype.nullptr(cintf.VMPROFSTACK)
+        cintf.vmprof_tl_stack.setraw(null)
+        self.meta_interp(main, [30], inline=True)
+        assert visited[:3] == [[(1, 12), (1, 8)], [(1, 12), (1, 8)], [(1, 12), 
(1, 8)]]
+
+
     def test_one(self):
 #        py.test.skip("needs thread-locals in the JIT, which is only available 
"
 #                     "after translation")
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
@@ -2082,10 +2082,30 @@
             raise NotImplementedError(oopspec_name)
 
     def _handle_rvmprof_call(self, op, oopspec_name, args):
-        if oopspec_name != 'rvmprof.code':
+        if oopspec_name != 'rvmprof.jitted':
             raise NotImplementedError(oopspec_name)
-        c_leaving, v_uniqueid = args
-        return SpaceOperation('rvmprof_code', [c_leaving, v_uniqueid], None)
+        c_entering = Constant(0, lltype.Signed)
+        c_leaving  = Constant(1, lltype.Signed)
+        v_uniqueid = args[0]
+        op1 = SpaceOperation('rvmprof_code', [c_entering, v_uniqueid], None)
+        op2 = SpaceOperation('rvmprof_code', [c_leaving, v_uniqueid], None)
+        #
+        # fish fish inside the oopspec's graph for the ll_func pointer
+        block = op.args[0].value._obj.graph.startblock
+        while True:
+            assert len(block.exits) == 1
+            nextblock = block.exits[0].target
+            if nextblock.operations == ():
+                break
+            block = nextblock
+        last_op = block.operations[-1]
+        assert last_op.opname == 'direct_call'
+        c_ll_func = last_op.args[0]
+        #
+        args = [c_ll_func] + op.args[2:]
+        ops = self.rewrite_op_direct_call(SpaceOperation('direct_call',
+                                                         args, op.result))
+        return [op1] + ops + [op2]
 
     def rewrite_op_ll_read_timestamp(self, op):
         op1 = self.prepare_builtin_call(op, "ll_read_timestamp", [])
diff --git a/rpython/jit/codewriter/test/test_flatten.py 
b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -1115,23 +1115,22 @@
         from rpython.rlib.rvmprof import cintf
         class MyFakeCallControl(FakeCallControl):
             def guess_call_kind(self, op):
-                if '_code' in repr(op):
+                if 'jitted' in repr(op):
                     return 'builtin'
                 return 'residual'
         class X:
             pass
-        def g():
+        def g(x, y):
             debug.debug_print("foo")
             return X()
-        g._dont_inline_ = True
-        def f(x):
-            cintf.jit_rvmprof_code(0, x)
-            res = g()
-            cintf.jit_rvmprof_code(1, x)
-            return res
-        self.encoding_test(f, [42], """
+        @jit.oopspec("rvmprof.jitted(unique_id)")
+        def decorated_jitted_function(unique_id, *args):
+            return g(*args)
+        def f(id, x, y):
+            return decorated_jitted_function(id, x, y)
+        self.encoding_test(f, [42, 56, 74], """
             rvmprof_code $0, %i0
-            residual_call_r_r $<* fn g>, R[], <Descr> -> %r0
+            residual_call_ir_r $<* fn g>, I[%i1, %i2], R[], <Descr> -> %r0
             -live-
             rvmprof_code $1, %i0
             ref_return %r0
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -7,6 +7,7 @@
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.rtyper.tool import rffi_platform as platform
 from rpython.rlib import rthread, jit
+from rpython.rlib.objectmodel import we_are_translated
 
 class VMProfPlatformUnsupported(Exception):
     pass
@@ -96,6 +97,8 @@
     return s
 
 def leave_code(s):
+    if not we_are_translated():
+        assert vmprof_tl_stack.getraw() == s
     vmprof_tl_stack.setraw(s.c_next)
     lltype.free(s, flavor='raw')
 
@@ -107,40 +110,35 @@
 #   (It uses kind == VMPROF_JITTED_TAG and the VMPROFSTACK is allocated
 #   in the C stack.)
 #
-# - The jitcode for decorated_jitted_function() in rvmprof.py, if
-#   we_are_jitted() calls the oopspec'ed function jit_rvmprof_code(),
-#   which turns into a simple jitcode opcode.  The jitcode has a
-#   simple structure:
+# - The jitcode for decorated_jitted_function() in rvmprof.py is
+#   special-cased by jtransform.py to produce this:
 #
 #        rvmprof_code(0, unique_id)
-#        res = inline_call FUNC
+#        res = inline_call FUNC         <- for func(*args)
 #        rvmprof_code(1, unique_id)
+#        return res
 #
-#   with no catch_exception logic for a "finally:" block.  Instead the
-#   blackhole interp looks for this simple pattern.  This is needed
-#   because, when a guard fails, the blackhole interp first rebuilds
-#   all the intermediate RPython frames; at that point it needs to
-#   call enter_code() on all intermediate RPython frames, so it does
-#   pattern matching to recognize frames and learn about unique_id.
+#   There is no 'catch_exception', but the second 'rvmprof_code' is
+#   meant to be executed even in case there was an exception.  This is
+#   done by a special case in pyjitpl.py and blackhole.py.  The point
+#   is that the above simple pattern can be detected by the blackhole
+#   interp, when it first rebuilds all the intermediate RPython
+#   frames; at that point it needs to call jit_enter_code() on all
+#   intermediate RPython frames, so it does pattern matching to
+#   recognize when it must call that and with which 'unique_id' value.
 #
 # - The jitcode opcode 'rvmprof_code' doesn't produce any resop.  When
-#   meta-interpreting, it causes pyjitpl to call jit_enter_code(), and
-#   jit_leave_code().  There is logic to call jit_leave_code() even if
-#   we exit with an exception, even though there is no
-#   'catch_exception'.
-#
-# - When blackholing, the call to jit_enter_code() occurs imediately
-#   as described above.  For calling jit_leave_code(), we use the same
-#   logic, detecting when we need to call it even though there is no
-#   'catch_exception'.
+#   meta-interpreting, it causes pyjitpl to call jit_enter_code() or
+#   jit_leave_code().  As mentioned above, there is logic to call
+#   jit_leave_code() even if we exit with an exception, even though
+#   there is no 'catch_exception'.  There is similar logic inside
+#   the blackhole interpreter.
 
[email protected]("rvmprof.code(leaving, unique_id)")
-def jit_rvmprof_code(leaving, unique_id):
-    """Marker for the JIT.  Also called directly from the metainterp and
-    the blackhole interp."""
-    if not leaving:
-        enter_code(unique_id)    # ignore the return value
-    else:
-        s = vmprof_tl_stack.getraw()
-        assert s.c_value == unique_id
-        leave_code(s)
+
+def jit_enter_code(unique_id):
+    enter_code(unique_id)    # ignore the return value
+
+def jit_leave_code(unique_id):
+    s = vmprof_tl_stack.getraw()
+    assert s.c_value == unique_id
+    leave_code(s)
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -178,12 +178,9 @@
         except cintf.VMProfPlatformUnsupported:
             return func
 
+        @jit.oopspec("rvmprof.jitted(unique_id)")
         def decorated_jitted_function(unique_id, *args):
-            cintf.jit_rvmprof_code(0, unique_id)
-            res = func(*args)
-            cintf.jit_rvmprof_code(1, unique_id)   # no 'finally:', see 
cintf.py
-            return res
-        decorated_jitted_function._dont_inline_ = True
+            return func(*args)
 
         def decorated_function(*args):
             unique_id = get_code_fn(*args)._vmprof_unique_id
@@ -195,7 +192,6 @@
                     leave_code(x)
             else:
                 return decorated_jitted_function(unique_id, *args)
-        decorated_function._always_inline_ = True
 
         decorated_function.__name__ = func.__name__ + '_rvmprof'
         return decorated_function
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to