Author: fijal
Branch: fix-trace-too-long-heuristic
Changeset: r80787:8b8b9dd15910
Date: 2015-11-20 11:43 +0200
http://bitbucket.org/pypy/pypy/changeset/8b8b9dd15910/

Log:    a bit undertested hooks to get the new abort hook going

diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -14,6 +14,7 @@
         'trace_next_iteration_hash': 'interp_jit.trace_next_iteration_hash',
         'set_compile_hook': 'interp_resop.set_compile_hook',
         'set_abort_hook': 'interp_resop.set_abort_hook',
+        'set_trace_too_long_hook': 'interp_resop.set_trace_too_long_hook',
         'get_stats_snapshot': 'interp_resop.get_stats_snapshot',
         'get_stats_asmmemmgr': 'interp_resop.get_stats_asmmemmgr',
         # those things are disabled because they have bugs, but if
diff --git a/pypy/module/pypyjit/hooks.py b/pypy/module/pypyjit/hooks.py
--- a/pypy/module/pypyjit/hooks.py
+++ b/pypy/module/pypyjit/hooks.py
@@ -28,6 +28,23 @@
             finally:
                 cache.in_recursion = False
 
+    def on_trace_too_long(self, jitdriver, greenkey, greenkey_repr):
+        space = self.space
+        cache = space.fromcache(Cache)
+        if cache.in_recursion:
+            return
+        if space.is_true(cache.w_trace_too_long_hook):
+            cache.in_recursion = True
+            try:
+                try:
+                    space.call_function(cache.w_trace_too_long_hook,
+                        space.wrap(jitdriver.name),
+                        wrap_greenkey(space, jitdriver, greenkey, 
greenkey_repr))
+                except OperationError, e:
+                    e.write_unraisable(space, "jit hook", 
cache.w_trace_too_long_hook)
+            finally:
+                cache.in_recursion = False
+
     def after_compile(self, debug_info):
         self._compile_hook(debug_info, is_bridge=False)
 
diff --git a/pypy/module/pypyjit/interp_resop.py 
b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -22,6 +22,7 @@
     def __init__(self, space):
         self.w_compile_hook = space.w_None
         self.w_abort_hook = space.w_None
+        self.w_trace_too_long_hook = space.w_None
 
     def getno(self):
         self.no += 1
@@ -79,6 +80,21 @@
     cache.w_abort_hook = w_hook
     cache.in_recursion = NonConstant(False)
 
+def set_trace_too_long_hook(space, w_hook):
+    """ set_trace_too_long_hook(hook)
+
+    Set a hook (callable) that will be called each time we abort
+    tracing because the trace is too long.
+
+    The hook will be called with the signature:
+
+        hook(jitdriver_name, greenkey)
+    """
+    cache = space.fromcache(Cache)
+    assert w_hook is not None
+    cache.w_trace_too_long_hook = w_hook
+    cache.in_recursion = NonConstant(False)
+
 def wrap_oplist(space, logops, operations, ops_offset=None):
     # this function is called from the JIT
     from rpython.jit.metainterp.resoperation import rop
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1889,6 +1889,9 @@
 
         self.box_names_memo = {}
 
+        self.aborted_tracing_jitdriver = None
+        self.aborted_tracing_greenkey = None
+
     def retrace_needed(self, trace, exported_state):
         self.partial_trace = trace
         self.retracing_from = len(self.history.operations) - 1
@@ -2228,6 +2231,15 @@
                     self.staticdata.logger_ops._make_log_operations(
                         self.box_names_memo),
                     self.history.operations)
+            if self.aborted_tracing_jitdriver is not None:
+                jd_sd = self.aborted_tracing_jitdriver
+                greenkey = self.aborted_tracing_greenkey
+                self.staticdata.warmrunnerdesc.hooks.on_trace_too_long(
+                    jd_sd.jitdriver, greenkey,
+                    jd_sd.warmstate.get_location_str(greenkey))
+                # no ops for now
+                self.aborted_tracing_jitdriver = None
+                self.aborted_tracing_greenkey = None
         self.staticdata.stats.aborted()
 
     def blackhole_if_trace_too_long(self):
@@ -2239,6 +2251,8 @@
             if greenkey_of_huge_function is not None:
                 jd_sd.warmstate.disable_noninlinable_function(
                     greenkey_of_huge_function)
+                self.aborted_tracing_jitdriver = jd_sd
+                self.aborted_tracing_greenkey = greenkey_of_huge_function
                 if self.current_merge_points:
                     jd_sd = self.jitdriver_sd
                     greenkey = 
self.current_merge_points[0][0][:jd_sd.num_green_args]
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1062,6 +1062,12 @@
         greenkey where it started, reason is a string why it got aborted
         """
 
+    def on_trace_too_long(self, jitdriver, greenkey, greenkey_repr):
+        """ A hook called each time we abort the trace because it's too
+        long with the greenkey being the one responsible for the
+        disabled function
+        """
+
     #def before_optimize(self, debug_info):
     #    """ A hook called before optimizer is run, called with instance of
     #    JitDebugInfo. Overwrite for custom behavior
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to