Author: Richard Plangger <planri...@gmail.com>
Branch: py3.5-str-opt
Changeset: r87756:0c7f33f0bab0
Date: 2016-10-13 15:45 +0200
http://bitbucket.org/pypy/pypy/changeset/0c7f33f0bab0/

Log:    merge default

diff --git a/lib-python/2.7/test/test_cmd_line.py 
b/lib-python/2.7/test/test_cmd_line.py
--- a/lib-python/2.7/test/test_cmd_line.py
+++ b/lib-python/2.7/test/test_cmd_line.py
@@ -75,7 +75,7 @@
         p.stdin.write('Timer\n')
         p.stdin.write('exit()\n')
         data = kill_python(p)
-        self.assertTrue(data.startswith('1 loop'))
+        self.assertIn('1 loop', data)
         self.assertIn('__main__.Timer', data)
 
     def test_run_code(self):
diff --git a/lib-python/2.7/test/test_timeit.py 
b/lib-python/2.7/test/test_timeit.py
--- a/lib-python/2.7/test/test_timeit.py
+++ b/lib-python/2.7/test/test_timeit.py
@@ -318,9 +318,8 @@
         s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 
'print("CustomSetup")'])
         self.assertIn(dedent("""\
             WARNING: timeit is a very unreliable tool. use perf or something 
else for real measurements
-            pypy -m pip install perf
-            pypy -m perf timeit -n35 -s 'print("CustomSetup")' 'import timeit; 
timeit._fake_timer.inc()'
         """), s)
+        self.assertIn("-m pip install perf", s)
 
 
 
diff --git a/lib-python/3/test/test_timeit.py b/lib-python/3/test/test_timeit.py
--- a/lib-python/3/test/test_timeit.py
+++ b/lib-python/3/test/test_timeit.py
@@ -12,7 +12,7 @@
 DEFAULT_NUMBER = 1000000
 
 # timeit's default number of repetitions.
-DEFAULT_REPEAT = 3
+DEFAULT_REPEAT = timeit.default_repeat
 
 # XXX: some tests are commented out that would improve the coverage but take a
 # long time to run because they test the default number of loops, which is
@@ -226,7 +226,7 @@
             t.print_exc(s)
         self.assert_exc_string(s.getvalue(), 'ZeroDivisionError')
 
-    MAIN_DEFAULT_OUTPUT = "10 loops, best of 3: 1 sec per loop\n"
+    MAIN_DEFAULT_OUTPUT = "1 loops, average of 7: 1 +- 0 sec per loop (using 
standard deviation)\n"
 
     def run_main(self, seconds_per_increment=1.0, switches=None, timer=None):
         if timer is None:
@@ -252,39 +252,41 @@
 
     def test_main_seconds(self):
         s = self.run_main(seconds_per_increment=5.5)
-        self.assertEqual(s, "10 loops, best of 3: 5.5 sec per loop\n")
+        self.assertIn("1 loops, average of 7: 5.5 +- 0 sec per loop (using 
standard deviation)\n", s)
 
     def test_main_milliseconds(self):
         s = self.run_main(seconds_per_increment=0.0055)
-        self.assertEqual(s, "100 loops, best of 3: 5.5 msec per loop\n")
+        self.assertIn("100 loops, average of 7: 5.5 +-", s)
+        self.assertIn("msec per loop", s)
 
     def test_main_microseconds(self):
         s = self.run_main(seconds_per_increment=0.0000025, switches=['-n100'])
-        self.assertEqual(s, "100 loops, best of 3: 2.5 usec per loop\n")
+        self.assertIn("100 loops, average of 7: 2.5", s)
+        self.assertIn("usec per loop", s)
 
     def test_main_fixed_iters(self):
         s = self.run_main(seconds_per_increment=2.0, switches=['-n35'])
-        self.assertEqual(s, "35 loops, best of 3: 2 sec per loop\n")
+        self.assertIn("35 loops, average of 7: 2 +- 0 sec per loop (using 
standard deviation)\n", s)
 
     def test_main_setup(self):
         s = self.run_main(seconds_per_increment=2.0,
                 switches=['-n35', '-s', 'print("CustomSetup")'])
-        self.assertEqual(s, "CustomSetup\n" * 3 +
-                "35 loops, best of 3: 2 sec per loop\n")
+        self.assertIn("CustomSetup\n" * DEFAULT_REPEAT +
+                "35 loops, average of 7: 2 +- 0 sec per loop (using standard 
deviation)\n", s)
 
     def test_main_multiple_setups(self):
         s = self.run_main(seconds_per_increment=2.0,
                 switches=['-n35', '-s', 'a = "CustomSetup"', '-s', 'print(a)'])
-        self.assertEqual(s, "CustomSetup\n" * 3 +
-                "35 loops, best of 3: 2 sec per loop\n")
+        self.assertIn("CustomSetup\n" * DEFAULT_REPEAT +
+                "35 loops, average of 7: 2 +- 0 sec per loop (using standard 
deviation)\n", s)
 
     def test_main_fixed_reps(self):
         s = self.run_main(seconds_per_increment=60.0, switches=['-r9'])
-        self.assertEqual(s, "10 loops, best of 9: 60 sec per loop\n")
+        self.assertIn("1 loops, average of 9: 60 +- 0 sec per loop (using 
standard deviation)\n", s)
 
     def test_main_negative_reps(self):
         s = self.run_main(seconds_per_increment=60.0, switches=['-r-5'])
-        self.assertEqual(s, "10 loops, best of 1: 60 sec per loop\n")
+        self.assertIn("1 loops, average of 1: 60 +- 0 sec per loop (using 
standard deviation)\n", s)
 
     @unittest.skipIf(sys.flags.optimize >= 2, "need __doc__")
     def test_main_help(self):
@@ -296,47 +298,54 @@
     def test_main_using_time(self):
         fake_timer = FakeTimer()
         s = self.run_main(switches=['-t'], timer=fake_timer)
-        self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT)
+        self.assertIn(self.MAIN_DEFAULT_OUTPUT, s)
         self.assertIs(fake_timer.saved_timer, time.time)
 
     def test_main_using_clock(self):
         fake_timer = FakeTimer()
         s = self.run_main(switches=['-c'], timer=fake_timer)
-        self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT)
+        self.assertIn(self.MAIN_DEFAULT_OUTPUT, s)
         self.assertIs(fake_timer.saved_timer, time.clock)
 
     def test_main_verbose(self):
         s = self.run_main(switches=['-v'])
-        self.assertEqual(s, dedent("""\
-                10 loops -> 10 secs
-                raw times: 10 10 10
-                10 loops, best of 3: 1 sec per loop
-            """))
+        self.assertIn(dedent("""\
+                1 loops -> 1 secs
+                raw times: 1 1 1 1 1 1 1
+                1 loops, average of 7: 1 +- 0 sec per loop (using standard 
deviation)
+            """), s)
 
     def test_main_very_verbose(self):
         s = self.run_main(seconds_per_increment=0.000050, switches=['-vv'])
-        self.assertEqual(s, dedent("""\
+        self.assertIn(dedent("""\
+                1 loops -> 5e-05 secs
                 10 loops -> 0.0005 secs
                 100 loops -> 0.005 secs
                 1000 loops -> 0.05 secs
                 10000 loops -> 0.5 secs
-                raw times: 0.5 0.5 0.5
-                10000 loops, best of 3: 50 usec per loop
-            """))
+                raw times: 0.5 0.5 0.5 0.5 0.5 0.5 0.5
+                10000 loops, average of 7: 50 +- 0 usec per loop (using 
standard deviation)
+            """), s)
 
     def test_main_with_time_unit(self):
         unit_sec = self.run_main(seconds_per_increment=0.002,
                 switches=['-u', 'sec'])
-        self.assertEqual(unit_sec,
-                "1000 loops, best of 3: 0.002 sec per loop\n")
+        self.assertIn("100 loops, average of 7: 0.002",
+                      unit_sec)
+        self.assertIn("sec per loop",
+                      unit_sec)
         unit_msec = self.run_main(seconds_per_increment=0.002,
                 switches=['-u', 'msec'])
-        self.assertEqual(unit_msec,
-                "1000 loops, best of 3: 2 msec per loop\n")
+        self.assertIn("100 loops, average of 7: 2",
+                      unit_msec)
+        self.assertIn("msec per loop",
+                      unit_msec)
         unit_usec = self.run_main(seconds_per_increment=0.002,
                 switches=['-u', 'usec'])
-        self.assertEqual(unit_usec,
-                "1000 loops, best of 3: 2e+03 usec per loop\n")
+        self.assertIn("100 loops, average of 7: 2e+03",
+                      unit_usec)
+        self.assertIn("usec per loop",
+                      unit_usec)
         # Test invalid unit input
         with captured_stderr() as error_stringio:
             invalid = self.run_main(seconds_per_increment=0.002,
@@ -354,6 +363,14 @@
             s = self.run_main(switches=['-n1', '1/0'])
         self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError')
 
+    def test_main_recommends_perf(self):
+        s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 
'print("CustomSetup")'])
+        self.assertIn(dedent("""\
+            WARNING: timeit is a very unreliable tool. use perf or something 
else for real measurements
+        """), s)
+        self.assertIn("-m pip install perf", s)
+
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib-python/3/timeit.py b/lib-python/3/timeit.py
--- a/lib-python/3/timeit.py
+++ b/lib-python/3/timeit.py
@@ -13,7 +13,7 @@
 
 Options:
   -n/--number N: how many times to execute 'statement' (default: see below)
-  -r/--repeat N: how many times to repeat the timer (default 3)
+  -r/--repeat N: how many times to repeat the timer (default 7)
   -s/--setup S: statement to be executed once initially (default 'pass').
                 Execution time of this setup statement is NOT timed.
   -p/--process: use time.process_time() (default is time.perf_counter())
@@ -51,6 +51,8 @@
 """
 
 import gc
+import math
+import os
 import sys
 import time
 import itertools
@@ -59,7 +61,7 @@
 
 dummy_src_name = "<timeit-src>"
 default_number = 1000000
-default_repeat = 3
+default_repeat = 7
 default_timer = time.perf_counter
 
 _globals = globals
@@ -173,7 +175,8 @@
         """
         it = itertools.repeat(None, number)
         gcold = gc.isenabled()
-        gc.disable()
+        if '__pypy__' not in sys.builtin_module_names:
+            gc.disable()    # only do that on CPython
         try:
             timing = self.inner(it, self.timer)
         finally:
@@ -236,6 +239,7 @@
     """
     if args is None:
         args = sys.argv[1:]
+    origargs = args
     import getopt
     try:
         opts, args = getopt.getopt(args, "n:u:s:r:tcpvh",
@@ -253,7 +257,7 @@
     repeat = default_repeat
     verbose = 0
     time_unit = None
-    units = {"usec": 1, "msec": 1e3, "sec": 1e6}
+    units = {'msec': 1000.0, 'usec': 1000000.0, 'sec': 1}
     precision = 3
     for o, a in opts:
         if o in ("-n", "--number"):
@@ -285,17 +289,25 @@
             print(__doc__, end=' ')
             return 0
     setup = "\n".join(setup) or "pass"
+
+    print("WARNING: timeit is a very unreliable tool. use perf or something 
else for real measurements")
+    executable = os.path.basename(sys.executable)
+    print("%s -m pip install perf" % executable)
+    print("%s -m perf timeit %s" % (
+        executable,
+        " ".join([(arg if arg.startswith("-") else repr(arg))
+                        for arg in origargs]), ))
+    print("-" * 60)
     # Include the current directory, so that local imports work (sys.path
     # contains the directory of this script, rather than the current
     # directory)
-    import os
     sys.path.insert(0, os.curdir)
     if _wrap_timer is not None:
         timer = _wrap_timer(timer)
     t = Timer(stmt, setup, timer)
     if number == 0:
         # determine number so that 0.2 <= total time < 2.0
-        for i in range(1, 10):
+        for i in range(0, 10):
             number = 10**i
             try:
                 x = t.timeit(number)
@@ -307,30 +319,38 @@
             if x >= 0.2:
                 break
     try:
-        r = t.repeat(repeat, number)
+        timings = t.repeat(repeat, number)
     except:
         t.print_exc()
         return 1
-    best = min(r)
     if verbose:
-        print("raw times:", " ".join(["%.*g" % (precision, x) for x in r]))
-    print("%d loops," % number, end=' ')
-    usec = best * 1e6 / number
-    if time_unit is not None:
-        print("best of %d: %.*g %s per loop" % (repeat, precision,
-                                             usec/units[time_unit], time_unit))
+        print("raw times:", " ".join(["%.*g" % (precision, x) for x in 
timings]))
+
+    timings = [dt / number for dt in timings]
+
+    def _avg(l):
+        return math.fsum(l) / len(l)
+    def _stdev(l):
+        avg = _avg(l)
+        return (math.fsum([(x - avg) ** 2 for x in l]) / len(l)) ** 0.5
+
+    average = _avg(timings)
+
+    if time_unit is None:
+        scales = [(scale, unit) for unit, scale in units.items()]
+        scales.sort()
+        for scale, time_unit in scales:
+            if average * scale >= 1.0:
+                 break
     else:
-        if usec < 1000:
-            print("best of %d: %.*g usec per loop" % (repeat, precision, usec))
-        else:
-            msec = usec / 1000
-            if msec < 1000:
-                print("best of %d: %.*g msec per loop" % (repeat,
-                                                          precision, msec))
-            else:
-                sec = msec / 1000
-                print("best of %d: %.*g sec per loop" % (repeat,
-                                                         precision, sec))
+        print(time_unit)
+        scale = units[time_unit]
+
+    stdev = _stdev(timings)
+    print("%s loops, average of %d: %.*g +- %.*g %s per loop (using standard 
deviation)"
+          % (number, repeat,
+             precision, average * scale,
+             precision, stdev * scale, time_unit))
     return None
 
 if __name__ == "__main__":
diff --git a/lib-python/3/weakref.py b/lib-python/3/weakref.py
--- a/lib-python/3/weakref.py
+++ b/lib-python/3/weakref.py
@@ -111,7 +111,14 @@
                 if self._iterating:
                     self._pending_removals.append(wr.key)
                 else:
-                    del self.data[wr.key]
+                    # Changed this for PyPy: made more resistent.  The
+                    # issue is that in some corner cases, self.data
+                    # might already be changed or removed by the time
+                    # this weakref's callback is called.  If that is
+                    # the case, we don't want to randomly kill an
+                    # unrelated entry.
+                    if self.data.get(wr.key) is wr:
+                        del self.data[wr.key]
         self._remove = remove
         # A list of keys to be removed
         self._pending_removals = []
@@ -239,24 +246,28 @@
         try:
             o = self.data.pop(key)()
         except KeyError:
+            o = None
+        if o is None:
             if args:
                 return args[0]
-            raise
-        if o is None:
             raise KeyError(key)
         else:
             return o
+        # The logic above was fixed in PyPy
 
     def setdefault(self, key, default=None):
         try:
-            wr = self.data[key]
+            o = self.data[key]()
         except KeyError:
+            o = None
+        if o is None:
             if self._pending_removals:
                 self._commit_removals()
             self.data[key] = KeyedRef(default, self._remove, key)
             return default
         else:
-            return wr()
+            return o
+        # The logic above was fixed in PyPy
 
     def update(*args, **kwargs):
         if not args:
diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py
--- a/pypy/module/thread/os_local.py
+++ b/pypy/module/thread/os_local.py
@@ -13,6 +13,7 @@
 
 
 ExecutionContext._thread_local_objs = None
+ExecutionContext._sentinel_lock = None
 
 
 class Local(W_Root):
@@ -90,6 +91,10 @@
                         )
 
 def thread_is_stopping(ec):
+    sentinel_lock = ec._sentinel_lock
+    if sentinel_lock is not None:
+        if sentinel_lock.lock.is_acquired():
+            sentinel_lock.descr_lock_release(ec.space)
     tlobjs = ec._thread_local_objs
     if tlobjs is None:
         return
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -11,7 +11,6 @@
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.interpreter.error import oefmt
 from rpython.rlib.rarithmetic import r_longlong, ovfcheck, 
ovfcheck_float_to_longlong
-from rpython.rlib.rthread import ThreadLocalReference
 
 # Force the declaration of the type 'thread.LockType' for RPython
 #import pypy.module.thread.rpython.exttable
@@ -147,8 +146,6 @@
 See LockType.__doc__ for information about locks."""
     return space.wrap(Lock(space))
 
-tlref_sentinel_lock = ThreadLocalReference(Lock)
-
 def _set_sentinel(space):
     """_set_sentinel() -> lock
 
@@ -158,12 +155,11 @@
     This is a private API for the threading module."""
     # see issue 18808. We need to release this lock just before exiting
     # the any thread!
-    lock = Lock(space)
-    # create a weak reference to the lock object and set it
-    # pass save it as a thread local reference
-    # see os_thread.py just before gc_thread_die
-    tlref_sentinel_lock.set(lock)
-    #
+    ec = space.getexecutioncontext()
+    lock = ec._sentinel_lock
+    if lock is None:
+        lock = Lock(space)
+        ec._sentinel_lock = lock
     return space.wrap(lock)
 
 class W_RLock(W_Root):
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -7,7 +7,6 @@
 from pypy.module.thread.error import wrap_thread_error
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import unwrap_spec, Arguments
-from pypy.module.thread.os_lock import tlref_sentinel_lock
 
 # Here are the steps performed to start a new thread:
 #
@@ -103,11 +102,6 @@
                 os.write(STDERR, "\n")
             except OSError:
                 pass
-        # TODO move after rthread.gc_thread_die()?
-        lock = tlref_sentinel_lock.get()
-        if lock and lock.descr_lock_locked(space):
-            lock.descr_lock_release(space)
-            tlref_sentinel_lock.set(None)
         #
         bootstrapper.nbthreads -= 1
         rthread.gc_thread_die()
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -64,8 +64,6 @@
 
     def setitem_str(self, w_dict, key, w_value):
         cell = self.getdictvalue_no_unwrapping(w_dict, key)
-        #if (key == '__package__' or key == "__path__") and cell is not None 
and w_value is not cell:
-        #    print "WARNING", key, w_value, cell, self
         return self._setitem_str_cell_known(cell, w_dict, key, w_value)
 
     def _setitem_str_cell_known(self, cell, w_dict, key, w_value):
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -734,7 +734,7 @@
         modifier = resume.ResumeDataVirtualAdder(self, descr, op, self.trace,
                                                  self.resumedata_memo)
         try:
-            newboxes = modifier.finish(self, pendingfields)
+            newboxes = modifier.finish(pendingfields)
             if (newboxes is not None and
                 len(newboxes) > self.metainterp_sd.options.failargs_limit):
                 raise resume.TagOverflow
diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py 
b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
--- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py
+++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
@@ -74,13 +74,13 @@
         descr = self.getfield_op.getdescr()
         if rop.is_getfield(g.opnum):
             cf = optheap.field_cache(descr)
-            opinfo.setfield(preamble_op.getdescr(), self.res, pop,
+            opinfo.setfield(preamble_op.getdescr(), g.getarg(0), pop,
                             optheap, cf)
         else:
             index = g.getarg(1).getint()
             assert index >= 0
             cf = optheap.arrayitem_cache(descr, index)
-            opinfo.setitem(self.getfield_op.getdescr(), index, self.res,
+            opinfo.setitem(self.getfield_op.getdescr(), index, g.getarg(0),
                            pop, optheap, cf)
 
     def repr(self, memo):
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -165,7 +165,7 @@
 class NumberingState(object):
     def __init__(self, size):
         self.liveboxes = {}
-        self.current = [0] * size
+        self.current = [rffi.cast(rffi.SHORT, 0)] * size
         self._pos = 0
         self.num_boxes = 0
         self.num_virtuals = 0
@@ -179,6 +179,9 @@
         assert rffi.cast(lltype.Signed, short) == item
         return self.append_short(short)
 
+    def create_numbering(self):
+        return resumecode.create_numbering(self.current)
+
 class ResumeDataLoopMemo(object):
 
     def __init__(self, metainterp_sd):
@@ -229,12 +232,12 @@
 
     # env numbering
 
-    def _number_boxes(self, iter, arr, optimizer, state):
+    def _number_boxes(self, iter, arr, optimizer, numb_state):
         """ Number boxes from one snapshot
         """
-        num_boxes = state.num_boxes
-        num_virtuals = state.num_virtuals
-        liveboxes = state.liveboxes
+        num_boxes = numb_state.num_boxes
+        num_virtuals = numb_state.num_virtuals
+        liveboxes = numb_state.liveboxes
         for item in arr:
             box = iter.get(rffi.cast(lltype.Signed, item))
             box = optimizer.get_box_replacement(box)
@@ -258,34 +261,34 @@
                     tagged = tag(num_boxes, TAGBOX)
                     num_boxes += 1
                 liveboxes[box] = tagged
-            state.append_short(tagged)
-        state.num_boxes = num_boxes
-        state.num_virtuals = num_virtuals
+            numb_state.append_short(tagged)
+        numb_state.num_boxes = num_boxes
+        numb_state.num_virtuals = num_virtuals
 
     def number(self, optimizer, position, trace):
         snapshot_iter = trace.get_snapshot_iter(position)
-        state = NumberingState(snapshot_iter.size)
+        numb_state = NumberingState(snapshot_iter.size)
 
         arr = snapshot_iter.vable_array
 
-        state.append_int(len(arr))
-        self._number_boxes(snapshot_iter, arr, optimizer, state)
+        numb_state.append_int(len(arr))
+        self._number_boxes(snapshot_iter, arr, optimizer, numb_state)
 
         arr = snapshot_iter.vref_array
         n = len(arr)
         assert not (n & 1)
-        state.append_int(n >> 1)
+        numb_state.append_int(n >> 1)
 
-        self._number_boxes(snapshot_iter, arr, optimizer, state)
+        self._number_boxes(snapshot_iter, arr, optimizer, numb_state)
 
         for snapshot in snapshot_iter.framestack:
             jitcode_index, pc = snapshot_iter.unpack_jitcode_pc(snapshot)
-            state.append_int(jitcode_index)
-            state.append_int(pc)
-            self._number_boxes(snapshot_iter, snapshot.box_array, optimizer, 
state)
+            numb_state.append_int(jitcode_index)
+            numb_state.append_int(pc)
+            self._number_boxes(
+                    snapshot_iter, snapshot.box_array, optimizer, numb_state)
 
-        numb = resumecode.create_numbering(state.current)
-        return numb, state.liveboxes, state.num_virtuals
+        return numb_state
 
 
     # caching for virtuals and boxes inside them
@@ -418,7 +421,8 @@
         _, tagbits = untag(tagged)
         return tagbits == TAGVIRTUAL
 
-    def finish(self, optimizer, pending_setfields=[]):
+    def finish(self, pending_setfields=[]):
+        optimizer = self.optimizer
         # compute the numbering
         storage = self.storage
         # make sure that nobody attached resume data to this guard yet
@@ -426,12 +430,12 @@
         resume_position = self.guard_op.rd_resume_position
         assert resume_position >= 0
         # count stack depth
-        numb, liveboxes_from_env, num_virtuals = self.memo.number(optimizer,
-            resume_position, self.optimizer.trace)
-        self.liveboxes_from_env = liveboxes_from_env
+        numb_state = self.memo.number(optimizer,
+            resume_position, optimizer.trace)
+        self.liveboxes_from_env = liveboxes_from_env = numb_state.liveboxes
+        num_virtuals = numb_state.num_virtuals
         self.liveboxes = {}
-        storage.rd_numb = numb
-        
+
         # collect liveboxes and virtuals
         n = len(liveboxes_from_env) - num_virtuals
         liveboxes = [None] * n
@@ -467,6 +471,7 @@
         self._number_virtuals(liveboxes, optimizer, num_virtuals)
         self._add_pending_fields(optimizer, pending_setfields)
 
+        storage.rd_numb = numb_state.create_numbering()
         storage.rd_consts = self.memo.consts
         return liveboxes[:]
 
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -551,8 +551,8 @@
           FakeFrame("code2", 9, c3, b2)]
     capture_resumedata(fs, None, [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
-    modifier = ResumeDataVirtualAdder(None, storage, storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer())
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo)
+    liveboxes = modifier.finish()
     metainterp = MyMetaInterp()
 
     b1t, b2t, b3t = [BoxInt(), InputArgRef(), BoxInt()]
@@ -575,8 +575,8 @@
           FakeFrame("code2", 9, c3, b2)]
     capture_resumedata(fs, [b4], [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
-    modifier = ResumeDataVirtualAdder(None, storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer({}))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage, memo)
+    liveboxes = modifier.finish()
     metainterp = MyMetaInterp()
 
     b1t, b2t, b3t, b4t = [BoxInt(), InputArgRef(), BoxInt(), InputArgRef()]
@@ -604,11 +604,11 @@
     capture_resumedata(fs, None, [], storage2)
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
-    modifier = ResumeDataVirtualAdder(None, storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer({}))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage, memo)
+    liveboxes = modifier.finish()
 
-    modifier = ResumeDataVirtualAdder(None, storage2, memo)
-    liveboxes2 = modifier.finish(FakeOptimizer({}))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage2, memo)
+    liveboxes2 = modifier.finish()
 
     metainterp = MyMetaInterp()
 
@@ -668,8 +668,8 @@
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
-    modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer(values))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo)
+    liveboxes = modifier.finish()
     assert len(storage.rd_virtuals) == 1
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
                                                 tag(0, TAGCONST)]
@@ -679,8 +679,8 @@
     v6.setfield(LLtypeMixin.nextdescr, v6)    
     values = {b2: virtual_value(b2, b4, v6), b6: v6}
     memo.clear_box_virtual_numbers()
-    modifier = ResumeDataVirtualAdder(storage2, memo)
-    liveboxes2 = modifier.finish(FakeOptimizer(values))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage2, memo)
+    liveboxes2 = modifier.finish()
     assert len(storage2.rd_virtuals) == 2    
     assert storage2.rd_virtuals[0].fieldnums == [tag(len(liveboxes2)-1, 
TAGBOX),
                                                  tag(-1, TAGVIRTUAL)]
@@ -725,8 +725,8 @@
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
-    modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer(values))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo)
+    liveboxes = modifier.finish()
     assert len(storage.rd_virtuals) == 1
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
                                                 tag(0, TAGCONST)]
@@ -735,8 +735,8 @@
     fs = [FakeFrame("code0", 0, b1, b4, b2)]
     capture_resumedata(fs, None, [], storage2)
     values[b4] = virtual_value(b4, b6, c4)
-    modifier = ResumeDataVirtualAdder(storage2, memo)
-    liveboxes = modifier.finish(FakeOptimizer(values))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage2, memo)
+    liveboxes = modifier.finish()
     assert len(storage2.rd_virtuals) == 2
     assert storage2.rd_virtuals[1].fieldnums == 
storage.rd_virtuals[0].fieldnums
     assert storage2.rd_virtuals[1] is storage.rd_virtuals[0]
@@ -754,8 +754,8 @@
     v2 = virtual_value(b2, b3, v1)
     v1.setfield(LLtypeMixin.nextdescr, v2)
     values = {b1: v1, b2: v2}
-    modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer(values))
+    modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo)
+    liveboxes = modifier.finish()
     assert liveboxes == [b3]
     assert len(storage.rd_virtuals) == 2
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
@@ -849,11 +849,12 @@
 
     iter = t.get_iter()
     b1, b2, b3, b4, b5 = iter.inputargs
-    numb, liveboxes, v = memo.number(FakeOptimizer(), 0, iter)
-    assert v == 0
+    numb_state = memo.number(FakeOptimizer(), 0, iter)
+    numb = numb_state.create_numbering()
+    assert numb_state.num_virtuals == 0
 
-    assert liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
-                         b3: tag(2, TAGBOX)}
+    assert numb_state.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
+                                    b3: tag(2, TAGBOX)}
     base = [0, 0, tag(0, TAGBOX), tag(1, TAGINT),
             tag(1, TAGBOX), tag(0, TAGBOX), tag(2, TAGINT)]
 
@@ -864,12 +865,13 @@
                                   False, [], [])
     snap2.prev = snap
 
-    numb2, liveboxes2, v = memo.number(FakeOptimizer(), 1, iter)
-    assert v == 0
-    
-    assert liveboxes2 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
-                         b3: tag(2, TAGBOX)}
-    assert liveboxes2 is not liveboxes
+    numb_state2 = memo.number(FakeOptimizer(), 1, iter)
+    numb2 = numb_state2.create_numbering()
+    assert numb_state2.num_virtuals == 0
+
+    assert numb_state2.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
+                                     b3: tag(2, TAGBOX)}
+    assert numb_state2.liveboxes is not numb_state.liveboxes
     assert unpack_numbering(numb2) == [0, 0] + base + [0, 2, tag(3, TAGINT), 
tag(2, TAGBOX),
                                        tag(0, TAGBOX), tag(3, TAGINT)]
 
@@ -887,10 +889,11 @@
 
     # renamed
     b3.set_forwarded(c4)
-    numb3, liveboxes3, v = memo.number(FakeOptimizer(), 2, iter)
-    assert v == 0
+    numb_state3 = memo.number(FakeOptimizer(), 2, iter)
+    numb3 = numb_state3.create_numbering()
+    assert numb_state3.num_virtuals == 0
     
-    assert liveboxes3 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)}
+    assert numb_state3.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)}
     assert unpack_numbering(numb3) == ([0, 2, tag(3, TAGINT), tag(4, TAGINT),
                                        tag(0, TAGBOX), tag(3, TAGINT)] +
                                        base + [0, 2])
@@ -902,11 +905,12 @@
     snap4.prev = snap
 
     b4.set_forwarded(FakeVirtualInfo(True))
-    numb4, liveboxes4, v = memo.number(FakeOptimizer(), 3, iter)
-    assert v == 1
+    numb_state4 = memo.number(FakeOptimizer(), 3, iter)
+    numb4 = numb_state4.create_numbering()
+    assert numb_state4.num_virtuals == 1
     
-    assert liveboxes4 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
-                          b4: tag(0, TAGVIRTUAL)}
+    assert numb_state4.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
+                                     b4: tag(0, TAGVIRTUAL)}
     assert unpack_numbering(numb4) == [0, 2, tag(3, TAGINT), tag(0, 
TAGVIRTUAL),
                                        tag(0, TAGBOX), tag(3, TAGINT)] + base 
+ [0, 2]
 
@@ -920,11 +924,12 @@
 
     b4.set_forwarded(FakeVirtualInfo(True))
     b5.set_forwarded(FakeVirtualInfo(True))
-    numb5, liveboxes5, v = memo.number(FakeOptimizer(), 4, iter)
-    assert v == 2
-    
-    assert liveboxes5 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
-                          b4: tag(0, TAGVIRTUAL), b5: tag(1, TAGVIRTUAL)}
+    numb_state5 = memo.number(FakeOptimizer(), 4, iter)
+    numb5 = numb_state5.create_numbering()
+    assert numb_state5.num_virtuals == 2
+
+    assert numb_state5.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
+                                     b4: tag(0, TAGVIRTUAL), b5: tag(1, 
TAGVIRTUAL)}
     assert unpack_numbering(numb5) == [
         3, tag(0, TAGBOX), tag(0, TAGVIRTUAL), tag(1, TAGVIRTUAL),
         0] + base + [
@@ -941,8 +946,9 @@
     i = t.get_iter()
     t.create_top_snapshot(FakeJitCode("", 0), 0, Frame(lst), False, [], [])
     memo = ResumeDataLoopMemo(metainterp_sd)
-    num, liveboxes, v = memo.number(FakeOptimizer(), 0, i)
-    l = unpack_numbering(num)
+    numb_state = memo.number(FakeOptimizer(), 0, i)
+    numb = numb_state.create_numbering()
+    l = unpack_numbering(numb)
     assert l[0] == 0
     assert l[1] == 0
     assert l[2] == 0
@@ -951,7 +957,7 @@
     for i, item in enumerate(lst):
         v, tag = untag(l[i + 4])
         if tag == TAGBOX:
-            assert l[i + 4] == liveboxes[mapping[item]]
+            assert l[i + 4] == numb_state.liveboxes[mapping[item]]
         elif tag == TAGCONST:
             assert memo.consts[v].getint() == item.getint()
         elif tag == TAGINT:
@@ -1059,7 +1065,7 @@
     memo = ResumeDataLoopMemo(metainterp_sd)  
     i = t.get_iter()
     modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, 
memo)
-    liveboxes = modifier.finish(FakeOptimizer(i))
+    liveboxes = modifier.finish()
     cpu = MyCPU([])
     reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe")
     reader.consume_vref_and_vable(None, None, None)
@@ -1077,7 +1083,7 @@
     memo = ResumeDataLoopMemo(metainterp_sd)
     i = t.get_iter()
     modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, 
memo)
-    modifier.finish(FakeOptimizer(i))
+    modifier.finish()
     assert len(memo.consts) == 2
     assert storage.rd_consts is memo.consts
 
@@ -1086,7 +1092,7 @@
     i = t.get_iter()
     modifier2 = ResumeDataVirtualAdder(FakeOptimizer(i), storage2, storage2,
                                        i, memo)
-    modifier2.finish(FakeOptimizer(i))
+    modifier2.finish()
     assert len(memo.consts) == 3    
     assert storage2.rd_consts is memo.consts
 
@@ -1155,7 +1161,7 @@
 
     b1s.set_forwarded(b1_2)
     b2s.set_forwarded(b1_2)
-    liveboxes = modifier.finish(FakeOptimizer())
+    liveboxes = modifier.finish()
     assert storage.rd_snapshot is None
     b1t, b3t = [InputArgInt(11), InputArgInt(33)]
     newboxes = _resume_remap(liveboxes, [b1_2, b3s], b1t, b3t)
@@ -1177,7 +1183,7 @@
     storage = make_storage(b1s, b2s, b3s)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())        
     modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo)
-    liveboxes = modifier.finish(FakeOptimizer())
+    liveboxes = modifier.finish()
     b2t, b3t = [InputArgRef(demo55o), InputArgInt(33)]
     newboxes = _resume_remap(liveboxes, [b2s, b3s], b2t, b3t)
     metainterp = MyMetaInterp()
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -129,6 +129,9 @@
     def acquire(self, flag):
         return True
 
+    def is_acquired(self):
+        return False
+
     def release(self):
         pass
 
@@ -164,6 +167,15 @@
             res = rffi.cast(lltype.Signed, res)
             return bool(res)
 
+    def is_acquired(self):
+        """ check if the lock is acquired (does not release the GIL) """
+        res = c_thread_acquirelock_timed_NOAUTO(
+            self._lock,
+            rffi.cast(rffi.LONGLONG, 0),
+            rffi.cast(rffi.INT, 0))
+        res = rffi.cast(lltype.Signed, res)
+        return not bool(res)
+
     def acquire_timed(self, timeout):
         """Timeout is in microseconds.  Returns 0 in case of failure,
         1 in case it works, 2 if interrupted by a signal."""
diff --git a/rpython/rlib/test/test_rthread.py 
b/rpython/rlib/test/test_rthread.py
--- a/rpython/rlib/test/test_rthread.py
+++ b/rpython/rlib/test/test_rthread.py
@@ -16,6 +16,14 @@
     res = ok1 and not ok2 and ok3
     assert res == 1
 
+def test_lock_is_aquired():
+    l = allocate_lock()
+    ok1 = l.acquire(True)
+    assert l.is_acquired() == True
+    assert l.is_acquired() == True
+    l.release()
+    assert l.is_acquired() == False
+
 def test_thread_error():
     l = allocate_lock()
     try:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to