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