Commits

Armin Rigo  committed bac656e

(rguillebert, arigo)

Add the options "pypy --jit=off" and "pypy --jit=default", turning
off the JIT or setting the default values. (The latter is only
useful if you use pypyjit.set_param("default"), actually.)

  • Participants
  • Parent commits 582d474

Comments (0)

Files changed (3)

File pypy/module/pypyjit/interp_jit.py

     '''Configure the tunable JIT parameters.
         * set_param(name=value, ...)            # as keyword arguments
         * set_param("name=value,name=value")    # as a user-supplied string
+        * set_param("off")                      # disable the jit
+        * set_param("default")                  # restore all defaults
     '''
     # XXXXXXXXX
     args_w, kwds_w = __args__.unpack()

File pypy/module/pypyjit/test/test_jit_setup.py

         # this just checks that the module is setting up things correctly, and
         # the resulting code makes sense on top of CPython.
         import pypyjit
-        pypyjit.set_param(threshold=5, inlining=1)
-        pypyjit.set_param("trace_eagerness=3,inlining=0")
+        try:
+            pypyjit.set_param(threshold=5, inlining=1)
+            pypyjit.set_param("trace_eagerness=3,inlining=0")
 
-        def f(x, y):
-            return x*y+1
+            def f(x, y):
+                return x*y+1
 
-        assert f(6, 7) == 43
+            assert f(6, 7) == 43
 
-        def gen(x):
-            i = 0
-            while i < x:
-                yield i*i
-                i += 1
+            def gen(x):
+                i = 0
+                while i < x:
+                    yield i*i
+                    i += 1
 
-        assert list(gen(3)) == [0, 1, 4]
+            assert list(gen(3)) == [0, 1, 4]
+        finally:
+            pypyjit.set_param('default')
+
+    def test_no_jit(self):
+        import pypyjit
+        was_called = []
+        def should_not_be_called(*args, **kwds):
+            was_called.append((args, kwds))
+        try:
+            pypyjit.set_param('off')
+            pypyjit.set_compile_hook(should_not_be_called)
+            def f():
+                pass
+            for i in range(2500):
+                f()
+            assert not was_called
+        finally:
+            pypyjit.set_compile_hook(None)
+            pypyjit.set_param('default')
+
 
 def test_interface_residual_call():
     space = gettestobjspace(usemodules=['pypyjit'])

File pypy/rlib/jit.py

               'enable_opts': None, # patched later by optimizeopt/__init__.py
               }
 unroll_parameters = unrolling_iterable(PARAMETERS.items())
+DEFAULT = object()
 
 # ____________________________________________________________
 
     def _set_param(self, name, value):
         # special-cased by ExtRegistryEntry
         # (internal, must receive a constant 'name')
+        # if value is DEFAULT, sets the default value.
         assert name in PARAMETERS
 
     @specialize.arg(0, 1)
                 return
         raise ValueError("no such parameter")
 
+    @specialize.arg(0, 1)
+    def set_param_to_default(self, name):
+        """Reset one of the tunable JIT parameters to its default value."""
+        for name1, _ in unroll_parameters:
+            if name1 == name:
+                self._set_param(name1, DEFAULT)
+                return
+        raise ValueError("no such parameter")
+
     def set_user_param(self, text):
         """Set the tunable JIT parameters from a user-supplied string
-        following the format 'param=value,param=value'.  For programmatic
-        setting of parameters, use directly JitDriver.set_param().
+        following the format 'param=value,param=value', or 'off' to
+        disable the JIT.  For programmatic setting of parameters, use
+        directly JitDriver.set_param().
         """
+        if text == 'off':
+            self.set_param('threshold', -1)
+            self.set_param('function_threshold', -1)
+            return
+        if text == 'default':
+            for name1, _ in unroll_parameters:
+                self.set_param_to_default(name1)
+            return
         for s in text.split(','):
             s = s.strip(' ')
             parts = s.split('=')
     def compute_result_annotation(self, s_name, s_value):
         from pypy.annotation import model as annmodel
         assert s_name.is_constant()
-        if s_name.const == 'enable_opts':
-            assert annmodel.SomeString(can_be_None=True).contains(s_value)
-        else:
-            assert annmodel.SomeInteger().contains(s_value)
+        if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value):
+            if s_name.const == 'enable_opts':
+                assert annmodel.SomeString(can_be_None=True).contains(s_value)
+            else:
+                assert annmodel.SomeInteger().contains(s_value)
         return annmodel.s_None
 
     def specialize_call(self, hop):
         from pypy.rpython.lltypesystem import lltype
         from pypy.rpython.lltypesystem.rstr import string_repr
+        from pypy.objspace.flow.model import Constant
 
         hop.exception_cannot_occur()
         driver = self.instance.im_self
             repr = string_repr
         else:
             repr = lltype.Signed
-        v_value = hop.inputarg(repr, arg=1)
+        if (isinstance(hop.args_v[1], Constant) and
+            hop.args_v[1].value is DEFAULT):
+            value = PARAMETERS[name]
+            v_value = hop.inputconst(repr, value)
+        else:
+            v_value = hop.inputarg(repr, arg=1)
         vlist = [hop.inputconst(lltype.Void, "set_param"),
                  hop.inputconst(lltype.Void, driver),
                  hop.inputconst(lltype.Void, name),