[pypy-commit] pypy default: merge heads
Author: Armin Rigo Branch: Changeset: r83479:96c8916a4c64 Date: 2016-04-01 09:44 +0200 http://bitbucket.org/pypy/pypy/changeset/96c8916a4c64/ Log:merge heads diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -181,9 +181,10 @@ elif space.is_w(space.type(w_obj), space.w_float): jit.promote(space.float_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_str): -jit.promote(space.str_w(w_obj)) +jit.promote_string(space.unicode_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_unicode): -jit.promote(space.unicode_w(w_obj)) +raise OperationError(space.w_TypeError, space.wrap( + "promoting unicode unsupported")) else: jit.promote(w_obj) return w_obj diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py --- a/rpython/jit/backend/zarch/pool.py +++ b/rpython/jit/backend/zarch/pool.py @@ -33,7 +33,7 @@ def ensure_can_hold_constants(self, asm, op): # allocates 8 bytes in memory for pointers, long integers or floats -if rop.is_jit_debug(op): +if rop.is_jit_debug(op.getopnum()): return for arg in op.getarglist(): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Add more tests
Author: Armin Rigo Branch: Changeset: r83478:ea5f0b463c5d Date: 2016-04-01 09:44 +0200 http://bitbucket.org/pypy/pypy/changeset/ea5f0b463c5d/ Log:Add more tests diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py --- a/pypy/module/operator/test/test_operator.py +++ b/pypy/module/operator/test/test_operator.py @@ -47,7 +47,13 @@ a.name = "hello" a.child = A() a.child.name = "world" +a.child.foo = "bar" assert attrgetter("child.name")(a) == "world" +assert attrgetter("child.name", "child.foo")(a) == ("world", "bar") + +def test_attrgetter_type(self): +from operator import attrgetter +assert type(attrgetter("child.name")) is attrgetter def test_concat(self): class Seq1: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Make attrgetter a single type -- this brings PyPy in line with CPython.
Author: Devin Jeanpierre Branch: Changeset: r83477:a13a0320f6f3 Date: 2016-03-31 16:15 -0700 http://bitbucket.org/pypy/pypy/changeset/a13a0320f6f3/ Log:Make attrgetter a single type -- this brings PyPy in line with CPython. e.g. code that does "if type(x) is operator.attrgetter:" now works. (I'm sorry.) Tested with stupid benchmarks and there is no significant difference. e.g.: (in pypy/pypy/module/operator): $ pypy -m timeit -s 'import operator; a = operator.attrgetter("real"); items = range(1)' 'for x in items: a(x)' 1 loops, best of 3: 71.7 usec per loop $ pypy -m timeit -s 'import app_operator as operator; a = operator.attrgetter("real"); items = range(1)' 'for x in items: a(x)' 1 loops, best of 3: 66.7 usec per loop $ pypy -m timeit -s 'import app_operator as operator; a = operator.attrgetter("real"); item = 1' 'a(1)' 1 loops, best of 3: 0.0073 usec per loop $ pypy -m timeit -s 'import operator; a = operator.attrgetter("real"); item = 1' 'a(1)' 1 loops, best of 3: 0.00694 usec per loop $ pypy -m timeit -s 'import app_operator as operator; a = operator.attrgetter("real.real"); items = range(1)' 'for x in items: a(x)' 1000 loops, best of 3: 501 usec per loop $ pypy -m timeit -s 'import operator; a = operator.attrgetter("real.real"); items = range(1)' 'for x in items: a(x)' 1000 loops, best of 3: 504 usec per loop $ pypy -m timeit -s 'import operator; a = operator.attrgetter("real.real", "real"); items = range(1)' 'for x in items: a(x)' 1000 loops, best of 3: 1.74 msec per loop $ pypy -m timeit -s 'import app_operator as operator; a = operator.attrgetter("real.real", "real"); items = range(1)' 'for x in items: a(x)' 1000 loops, best of 3: 1.82 msec per loop diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py --- a/pypy/module/operator/app_operator.py +++ b/pypy/module/operator/app_operator.py @@ -79,54 +79,45 @@ else: return _resolve_attr_chain(chain, obj, idx + 1) - -class _simple_attrgetter(object): -def __init__(self, attr): -self._attr = attr +class attrgetter(object): +def __init__(self, attr, *attrs): +if ( +not isinstance(attr, basestring) or +not all(isinstance(a, basestring) for a in attrs) +): +def _raise_typeerror(obj): +raise TypeError( +"argument must be a string, not %r" % type(attr).__name__ +) +self._call = _raise_typeerror +elif attrs: +self._multi_attrs = [ +a.split(".") for a in [attr] + list(attrs) +] +self._call = self._multi_attrgetter +elif "." not in attr: +self._simple_attr = attr +self._call = self._simple_attrgetter +else: +self._single_attr = attr.split(".") +self._call = self._single_attrgetter def __call__(self, obj): -return getattr(obj, self._attr) +return self._call(obj) +def _simple_attrgetter(self, obj): +return getattr(obj, self._simple_attr) -class _single_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs +def _single_attrgetter(self, obj): +return _resolve_attr_chain(self._single_attr, obj) -def __call__(self, obj): -return _resolve_attr_chain(self._attrs, obj) - - -class _multi_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs - -def __call__(self, obj): +def _multi_attrgetter(self, obj): return tuple([ _resolve_attr_chain(attrs, obj) -for attrs in self._attrs +for attrs in self._multi_attrs ]) -def attrgetter(attr, *attrs): -if ( -not isinstance(attr, basestring) or -not all(isinstance(a, basestring) for a in attrs) -): -def _raise_typeerror(obj): -raise TypeError( -"argument must be a string, not %r" % type(attr).__name__ -) -return _raise_typeerror -if attrs: -return _multi_attrgetter([ -a.split(".") for a in [attr] + list(attrs) -]) -elif "." not in attr: -return _simple_attrgetter(attr) -else: -return _single_attrgetter(attr.split(".")) - - class itemgetter(object): def __init__(self, item, *items): self._single = not bool(items) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: remove unused dict
Author: Armin Rigo Branch: Changeset: r83480:ce466388b1be Date: 2016-04-01 09:45 +0200 http://bitbucket.org/pypy/pypy/changeset/ce466388b1be/ Log:remove unused dict diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -279,7 +279,6 @@ self._bigints = [] self._bigints_dict = {} self._floats = [] -self._floats_dict = {} self._snapshots = [] for i, inparg in enumerate(inputargs): inparg.set_position(i) @@ -305,7 +304,6 @@ self._bigints_dict = {} self._refs_dict = llhelper.new_ref_dict_3() -self._floats_dict = {} debug_start("jit-trace-done") debug_print("trace length: " + str(self._pos)) debug_print(" total snapshots: " + str(self._total_snapshots)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Add a warning to the docstring
Author: Armin Rigo Branch: Changeset: r83481:5731bf1c66b3 Date: 2016-04-01 09:52 +0200 http://bitbucket.org/pypy/pypy/changeset/5731bf1c66b3/ Log:Add a warning to the docstring diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -172,7 +172,7 @@ def _promote(space, w_obj): """ Promote the first argument of the function and return it. Promote is by value for ints, floats, strs, unicodes (but not subclasses thereof) and by -reference otherwise. +reference otherwise. (Unicodes not supported right now.) This function is experimental!""" from rpython.rlib import jit ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy new-jit-log: merged default, translation issue
Author: Richard Plangger Branch: new-jit-log Changeset: r83482:132688540925 Date: 2016-04-01 09:53 +0200 http://bitbucket.org/pypy/pypy/changeset/132688540925/ Log:merged default, translation issue diff --git a/pypy/doc/__pypy__-module.rst b/pypy/doc/__pypy__-module.rst --- a/pypy/doc/__pypy__-module.rst +++ b/pypy/doc/__pypy__-module.rst @@ -18,6 +18,7 @@ - ``bytebuffer(length)``: return a new read-write buffer of the given length. It works like a simplified array of characters (actually, depending on the configuration the ``array`` module internally uses this). + - ``attach_gdb()``: start a GDB at the interpreter-level (or a PDB before translation). Transparent Proxy Functionality @@ -37,4 +38,3 @@ - ``isfake(obj)``: returns True if ``obj`` is faked. - - ``interp_pdb()``: start a pdb at interpreter-level. diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -90,6 +90,7 @@ 'save_module_content_for_future_reload': 'interp_magic.save_module_content_for_future_reload', 'decode_long' : 'interp_magic.decode_long', +'_promote' : 'interp_magic._promote', } if sys.platform == 'win32': interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp' diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -168,3 +168,22 @@ except InvalidEndiannessError: raise oefmt(space.w_ValueError, "invalid byteorder argument") return space.newlong_from_rbigint(result) + +def _promote(space, w_obj): +""" Promote the first argument of the function and return it. Promote is by +value for ints, floats, strs, unicodes (but not subclasses thereof) and by +reference otherwise. + +This function is experimental!""" +from rpython.rlib import jit +if space.is_w(space.type(w_obj), space.w_int): +jit.promote(space.int_w(w_obj)) +elif space.is_w(space.type(w_obj), space.w_float): +jit.promote(space.float_w(w_obj)) +elif space.is_w(space.type(w_obj), space.w_str): +jit.promote(space.str_w(w_obj)) +elif space.is_w(space.type(w_obj), space.w_unicode): +jit.promote(space.unicode_w(w_obj)) +else: +jit.promote(w_obj) +return w_obj diff --git a/pypy/module/__pypy__/test/test_magic.py b/pypy/module/__pypy__/test/test_magic.py --- a/pypy/module/__pypy__/test/test_magic.py +++ b/pypy/module/__pypy__/test/test_magic.py @@ -47,3 +47,16 @@ assert decode_long('\x00\x80', 'little', False) == 32768 assert decode_long('\x00\x80', 'little', True) == -32768 raises(ValueError, decode_long, '', 'foo') + +def test_promote(self): +from __pypy__ import _promote +assert _promote(1) == 1 +assert _promote(1.1) == 1.1 +assert _promote("abc") == "abc" +assert _promote(u"abc") == u"abc" +l = [] +assert _promote(l) is l +class A(object): +pass +a = A() +assert _promote(a) is a diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -534,7 +534,7 @@ looptoken._ll_function_addr = rawstart if logger: log = logger.log_trace(MARK_TRACE_ASM, None, self.mc) -log.write(inputargs, operations, None, ops_offset, unique_id=unique_id) +log.write(inputargs, operations, None, ops_offset=ops_offset, unique_id=unique_id) self.fixup_target_tokens(rawstart) self.teardown() # oprofile support @@ -647,15 +647,28 @@ pass elif gloc is not bloc: self.mov(gloc, bloc) +offset = self.mc.get_relative_pos() self.mc.JMP_l(0) +self.mc.writeimm32(0) self.mc.force_frame_size(DEFAULT_FRAME_BYTES) -offset = self.mc.get_relative_pos() - 4 rawstart = self.materialize_loop(looptoken) -# update the jump to the real trace -self._patch_jump_for_descr(rawstart + offset, asminfo.rawstart) +# update the jump (above) to the real trace +self._patch_jump_to(rawstart + offset, asminfo.rawstart) # update the guard to jump right to this custom piece of assembler self.patch_jump_for_descr(faildescr, rawstart) +def _patch_jump_to(self, adr_jump_offset, adr_new_target): +assert adr_jump_offset != 0 +offset = adr_new_target - (adr_jump_offset + 5) +mc = codebuf.MachineCodeBlockWrapper() +mc.force_frame_size(DEFAULT_FRAME_BYTES) +if rx86.fits_in_32bits(offset): +mc.JMP_l(offset) +
[pypy-commit] pypy default: Another translation fix attempt
Author: Armin Rigo Branch: Changeset: r83483:648874ef8243 Date: 2016-04-01 09:30 +0100 http://bitbucket.org/pypy/pypy/changeset/648874ef8243/ Log:Another translation fix attempt diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -181,7 +181,7 @@ elif space.is_w(space.type(w_obj), space.w_float): jit.promote(space.float_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_str): -jit.promote_string(space.unicode_w(w_obj)) +jit.promote_string(space.str_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_unicode): raise OperationError(space.w_TypeError, space.wrap( "promoting unicode unsupported")) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy new-jit-log: refactoring the jitlog, inlines encode methods, finish_once of cpu now prints enter count of bridges, entries and loops
Author: Richard Plangger Branch: new-jit-log Changeset: r83484:992293e7c5b7 Date: 2016-04-01 10:56 +0200 http://bitbucket.org/pypy/pypy/changeset/992293e7c5b7/ Log:refactoring the jitlog, inlines encode methods, finish_once of cpu now prints enter count of bridges,entries and loops diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -352,7 +352,7 @@ self.loop_run_counters.append(struct) return struct -def finish_once(self): +def finish_once(self, jitlog): if self._debug: debug_start('jit-backend-counts') for i in range(len(self.loop_run_counters)): @@ -372,6 +372,11 @@ debug_print(prefix + ':' + str(struct.i)) debug_stop('jit-backend-counts') +if jitlog: +# this is always called, the jitlog knows if it is enabled +for i, struct in enumerate(self.loop_run_counters): +jitlog.log_jit_counter(struct) + @staticmethod @rgc.no_collect def _reacquire_gil_asmgcc(css, old_rpy_fastgil): diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -65,8 +65,8 @@ self.assembler.setup_once() @rgc.no_release_gil -def finish_once(self): -self.assembler.finish_once() +def finish_once(self, jitlog=None): +self.assembler.finish_once(jitlog) self.profile_agent.shutdown() def dump_loop_token(self, looptoken): diff --git a/rpython/jit/metainterp/jitlog.py b/rpython/jit/metainterp/jitlog.py --- a/rpython/jit/metainterp/jitlog.py +++ b/rpython/jit/metainterp/jitlog.py @@ -3,7 +3,7 @@ from rpython.jit.metainterp.history import ConstInt, ConstFloat from rpython.rlib.objectmodel import we_are_translated from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id +from rpython.rlib.objectmodel import compute_unique_id, always_inline import sys import weakref @@ -25,8 +25,42 @@ # the machine code was patched (e.g. guard) MARK_STITCH_BRIDGE = 0x19 +MARK_JIT_LOOP_COUNTER = 0x20 +MARK_JIT_BRIDGE_COUNTER = 0x21 +MARK_JIT_ENTRY_COUNTER = 0x22 + IS_32_BIT = sys.maxint == 2**31-1 +@always_inline +def encode_str(string): +return encode_le_32bit(len(string)) + string + +@always_inline +def encode_le_16bit(val): +return chr((val >> 0) & 0xff) + chr((val >> 8) & 0xff) + +@always_inline +def encode_le_32bit(val): +return ''.join([chr((val >> 0) & 0xff), +chr((val >> 8) & 0xff), +chr((val >> 16) & 0xff), +chr((val >> 24) & 0xff)]) + +@always_inline +def encode_le_addr(val): +if IS_32_BIT: +return encode_be_32bit(val) +else: +return ''.join([chr((val >> 0) & 0xff), +chr((val >> 8) & 0xff), +chr((val >> 16) & 0xff), +chr((val >> 24) & 0xff), +chr((val >> 32) & 0xff), +chr((val >> 40) & 0xff), +chr((val >> 48) & 0xff), +chr((val >> 56)& 0xff)]) + + class VMProfJitLogger(object): def __init__(self): @@ -37,24 +71,40 @@ def setup_once(self): self.is_setup = True self.cintf.jitlog_try_init_using_env() -if self.cintf.jitlog_filter(0x0): +if not self.cintf.jitlog_enabled(): return count = len(resoperations.opname) mark = MARK_RESOP_META for opnum, opname in resoperations.opname.items(): -line = self.encode_le_16bit(opnum) + self.encode_str(opname.lower()) -self.write_marked(mark, line) +line = encode_le_16bit(opnum) + encode_str(opname.lower()) +self._write_marked(mark, line) def teardown(self): self.cintf.jitlog_teardown() -def write_marked(self, mark, line): +def _write_marked(self, mark, line): +if not we_are_translated(): +assert self.cintf.jitlog_enabled() if not self.is_setup: self.setup_once() self.cintf.jitlog_write_marked(mark, line, len(line)) +def log_jit_counter(self, struct): +if not self.cintf.jitlog_enabled(): +return EMPTY_TRACE_LOG +le_addr = encode_le_addr(struct.number) +# not an address (but a number) but it is a machine word +le_count = encode_le_addr(struct.i) +if struct.type == 'l': +tag = MARK_JIT_LOOP_COUNTER +elif struct.type == 'b': +tag = MARK_JIT_BRIDGE_COUNTER +else: +tag = MARK_JIT_ENTRY_COUNTER +self._write_marked(tag, le_addr + le_count) + def log_trace(self, tag, metainterp_sd, mc, mem
[pypy-commit] pypy new-jit-log: catchup default
Author: Richard Plangger Branch: new-jit-log Changeset: r83485:6f53abf601b1 Date: 2016-04-01 10:57 +0200 http://bitbucket.org/pypy/pypy/changeset/6f53abf601b1/ Log:catchup default diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -172,7 +172,7 @@ def _promote(space, w_obj): """ Promote the first argument of the function and return it. Promote is by value for ints, floats, strs, unicodes (but not subclasses thereof) and by -reference otherwise. +reference otherwise. (Unicodes not supported right now.) This function is experimental!""" from rpython.rlib import jit @@ -181,9 +181,10 @@ elif space.is_w(space.type(w_obj), space.w_float): jit.promote(space.float_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_str): -jit.promote(space.str_w(w_obj)) +jit.promote_string(space.str_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_unicode): -jit.promote(space.unicode_w(w_obj)) +raise OperationError(space.w_TypeError, space.wrap( + "promoting unicode unsupported")) else: jit.promote(w_obj) return w_obj diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py --- a/pypy/module/operator/app_operator.py +++ b/pypy/module/operator/app_operator.py @@ -79,54 +79,45 @@ else: return _resolve_attr_chain(chain, obj, idx + 1) - -class _simple_attrgetter(object): -def __init__(self, attr): -self._attr = attr +class attrgetter(object): +def __init__(self, attr, *attrs): +if ( +not isinstance(attr, basestring) or +not all(isinstance(a, basestring) for a in attrs) +): +def _raise_typeerror(obj): +raise TypeError( +"argument must be a string, not %r" % type(attr).__name__ +) +self._call = _raise_typeerror +elif attrs: +self._multi_attrs = [ +a.split(".") for a in [attr] + list(attrs) +] +self._call = self._multi_attrgetter +elif "." not in attr: +self._simple_attr = attr +self._call = self._simple_attrgetter +else: +self._single_attr = attr.split(".") +self._call = self._single_attrgetter def __call__(self, obj): -return getattr(obj, self._attr) +return self._call(obj) +def _simple_attrgetter(self, obj): +return getattr(obj, self._simple_attr) -class _single_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs +def _single_attrgetter(self, obj): +return _resolve_attr_chain(self._single_attr, obj) -def __call__(self, obj): -return _resolve_attr_chain(self._attrs, obj) - - -class _multi_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs - -def __call__(self, obj): +def _multi_attrgetter(self, obj): return tuple([ _resolve_attr_chain(attrs, obj) -for attrs in self._attrs +for attrs in self._multi_attrs ]) -def attrgetter(attr, *attrs): -if ( -not isinstance(attr, basestring) or -not all(isinstance(a, basestring) for a in attrs) -): -def _raise_typeerror(obj): -raise TypeError( -"argument must be a string, not %r" % type(attr).__name__ -) -return _raise_typeerror -if attrs: -return _multi_attrgetter([ -a.split(".") for a in [attr] + list(attrs) -]) -elif "." not in attr: -return _simple_attrgetter(attr) -else: -return _single_attrgetter(attr.split(".")) - - class itemgetter(object): def __init__(self, item, *items): self._single = not bool(items) diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py --- a/pypy/module/operator/test/test_operator.py +++ b/pypy/module/operator/test/test_operator.py @@ -47,7 +47,13 @@ a.name = "hello" a.child = A() a.child.name = "world" +a.child.foo = "bar" assert attrgetter("child.name")(a) == "world" +assert attrgetter("child.name", "child.foo")(a) == ("world", "bar") + +def test_attrgetter_type(self): +from operator import attrgetter +assert type(attrgetter("child.name")) is attrgetter def test_concat(self): class Seq1: diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -279,7 +279,6 @@ self._bigints = [] self._bigints_dict = {} self._floats = [] -self._floats_dict = {} self._snapshots = []
[pypy-commit] pypy default: backout the merge of the branch we need to think more about
Author: fijal Branch: Changeset: r83486:56c0228015a1 Date: 2016-04-01 12:01 +0200 http://bitbucket.org/pypy/pypy/changeset/56c0228015a1/ Log:backout the merge of the branch we need to think more about diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -277,9 +277,18 @@ raise NotImplementedError def get_traceback(self): -"""Get the PyTraceback object, for app-level Python code. +"""Calling this marks the PyTraceback as escaped, i.e. it becomes +accessible and inspectable by app-level Python code. For the JIT. +Note that this has no effect if there are already several traceback +frames recorded, because in this case they are already marked as +escaping by executioncontext.leave() being called with +got_exception=True. """ -return self._application_traceback +from pypy.interpreter.pytraceback import PyTraceback +tb = self._application_traceback +if tb is not None and isinstance(tb, PyTraceback): +tb.frame.mark_as_escaped() +return tb def set_traceback(self, traceback): """Set the current traceback.""" diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -74,6 +74,15 @@ finally: frame_vref = self.topframeref self.topframeref = frame.f_backref +if frame.escaped or got_exception: +# if this frame escaped to applevel, we must ensure that also +# f_back does +f_back = frame.f_backref() +if f_back: +f_back.mark_as_escaped() +# force the frame (from the JIT point of view), so that it can +# be accessed also later +frame_vref() jit.virtual_ref_finish(frame_vref, frame) # diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -65,6 +65,7 @@ last_exception = None f_backref= jit.vref_None +escaped = False # see mark_as_escaped() debugdata= None pycode = None # code object executed by that frame @@ -151,6 +152,15 @@ assert isinstance(cell, Cell) return cell +def mark_as_escaped(self): +""" +Must be called on frames that are exposed to applevel, e.g. by +sys._getframe(). This ensures that the virtualref holding the frame +is properly forced by ec.leave(), and thus the frame will be still +accessible even after the corresponding C stack died. +""" +self.escaped = True + def append_block(self, block): assert block.previous is self.lastblock self.lastblock = block diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -37,6 +37,7 @@ raise OperationError(space.w_ValueError, space.wrap("call stack is not deep enough")) if depth == 0: +f.mark_as_escaped() return space.wrap(f) depth -= 1 f = ec.getnextframe_nohidden(f) diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -475,6 +475,8 @@ def __call__(self): if self._state == 'non-forced': self._state = 'forced' +elif self._state == 'invalid': +raise InvalidVirtualRef return self._x @property @@ -485,7 +487,7 @@ def _finish(self): if self._state == 'non-forced': -self._state = 'forgotten' +self._state = 'invalid' class DirectJitVRef(DirectVRef): def __init__(self, x): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge
Author: fijal Branch: Changeset: r83487:325494587c00 Date: 2016-04-01 12:04 +0200 http://bitbucket.org/pypy/pypy/changeset/325494587c00/ Log:merge diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -172,7 +172,7 @@ def _promote(space, w_obj): """ Promote the first argument of the function and return it. Promote is by value for ints, floats, strs, unicodes (but not subclasses thereof) and by -reference otherwise. +reference otherwise. (Unicodes not supported right now.) This function is experimental!""" from rpython.rlib import jit @@ -181,7 +181,7 @@ elif space.is_w(space.type(w_obj), space.w_float): jit.promote(space.float_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_str): -jit.promote_string(space.unicode_w(w_obj)) +jit.promote_string(space.str_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_unicode): raise OperationError(space.w_TypeError, space.wrap( "promoting unicode unsupported")) diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py --- a/pypy/module/operator/app_operator.py +++ b/pypy/module/operator/app_operator.py @@ -79,54 +79,45 @@ else: return _resolve_attr_chain(chain, obj, idx + 1) - -class _simple_attrgetter(object): -def __init__(self, attr): -self._attr = attr +class attrgetter(object): +def __init__(self, attr, *attrs): +if ( +not isinstance(attr, basestring) or +not all(isinstance(a, basestring) for a in attrs) +): +def _raise_typeerror(obj): +raise TypeError( +"argument must be a string, not %r" % type(attr).__name__ +) +self._call = _raise_typeerror +elif attrs: +self._multi_attrs = [ +a.split(".") for a in [attr] + list(attrs) +] +self._call = self._multi_attrgetter +elif "." not in attr: +self._simple_attr = attr +self._call = self._simple_attrgetter +else: +self._single_attr = attr.split(".") +self._call = self._single_attrgetter def __call__(self, obj): -return getattr(obj, self._attr) +return self._call(obj) +def _simple_attrgetter(self, obj): +return getattr(obj, self._simple_attr) -class _single_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs +def _single_attrgetter(self, obj): +return _resolve_attr_chain(self._single_attr, obj) -def __call__(self, obj): -return _resolve_attr_chain(self._attrs, obj) - - -class _multi_attrgetter(object): -def __init__(self, attrs): -self._attrs = attrs - -def __call__(self, obj): +def _multi_attrgetter(self, obj): return tuple([ _resolve_attr_chain(attrs, obj) -for attrs in self._attrs +for attrs in self._multi_attrs ]) -def attrgetter(attr, *attrs): -if ( -not isinstance(attr, basestring) or -not all(isinstance(a, basestring) for a in attrs) -): -def _raise_typeerror(obj): -raise TypeError( -"argument must be a string, not %r" % type(attr).__name__ -) -return _raise_typeerror -if attrs: -return _multi_attrgetter([ -a.split(".") for a in [attr] + list(attrs) -]) -elif "." not in attr: -return _simple_attrgetter(attr) -else: -return _single_attrgetter(attr.split(".")) - - class itemgetter(object): def __init__(self, item, *items): self._single = not bool(items) diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py --- a/pypy/module/operator/test/test_operator.py +++ b/pypy/module/operator/test/test_operator.py @@ -47,7 +47,13 @@ a.name = "hello" a.child = A() a.child.name = "world" +a.child.foo = "bar" assert attrgetter("child.name")(a) == "world" +assert attrgetter("child.name", "child.foo")(a) == ("world", "bar") + +def test_attrgetter_type(self): +from operator import attrgetter +assert type(attrgetter("child.name")) is attrgetter def test_concat(self): class Seq1: diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -279,7 +279,6 @@ self._bigints = [] self._bigints_dict = {} self._floats = [] -self._floats_dict = {} self._snapshots = [] for i, inparg in enumerate(inputargs): inparg.set_position(i) @@ -305,7 +304,6 @@ self._bigints_dict
[pypy-commit] pypy new-jit-log: try init from env variable rewritten, there is currently no filtering mechanism. filtering does not make sense anymore
Author: Richard Plangger Branch: new-jit-log Changeset: r83490:b8dc684ce886 Date: 2016-04-01 12:50 +0200 http://bitbucket.org/pypy/pypy/changeset/b8dc684ce886/ Log:try init from env variable rewritten, there is currently no filtering mechanism. filtering does not make sense anymore diff --git a/rpython/rlib/rvmprof/src/jitlog_main.h b/rpython/rlib/rvmprof/src/jitlog_main.h --- a/rpython/rlib/rvmprof/src/jitlog_main.h +++ b/rpython/rlib/rvmprof/src/jitlog_main.h @@ -21,53 +21,22 @@ char *filename = getenv("JITLOG"); if (filename && filename[0]) { -char *newfilename = NULL, *escape; -char *colon = strchr(filename, ':'); -if (filename[0] == '+') { -filename += 1; -colon = NULL; +// mode is 775 +mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; +jitlog_fd = open(filename, O_WRONLY | O_CREAT, mode); +if (jitlog_fd == -1) { +perror("could not open"); +exit(-1); } -if (!colon) { -/* JITLOG=+filename (or just 'filename') --- profiling version */ -//pypy_setup_profiling(); -} else { -/* JITLOG=prefix:filename --- conditional logging */ -int n = colon - filename; -jitlog_prefix = malloc(n + 1); -memcpy(jitlog_prefix, filename, n); -//debug_prefix[n] = '\0'; -filename = colon + 1; -} -escape = strstr(filename, "%d"); -if (escape) { -/* a "%d" in the filename is replaced with the pid */ -newfilename = malloc(strlen(filename) + 32); -if (newfilename != NULL) { -char *p = newfilename; -memcpy(p, filename, escape - filename); -p += escape - filename; -sprintf(p, "%ld", (long)getpid()); -strcat(p, escape + 2); -filename = newfilename; -} -} -if (strcmp(filename, "-") != 0) { -// mode is 775 -mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; -jitlog_fd = open(filename, O_WRONLY | O_CREAT, mode); -} - -if (escape) { -free(newfilename); /* if not null */ -/* the env var is kept and passed to subprocesses */ - } else { +} else { +jitlog_ready = 0; +return; +} #ifndef _WIN32 - unsetenv("JITLOG"); +unsetenv("JITLOG"); #else - putenv("JITLOG="); +putenv("JITLOG="); #endif - } -} jitlog_ready = 1; } ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy new-jit-log: do not release gil for two logger functions. they are called in @rgc.no_release_gil
Author: Richard Plangger Branch: new-jit-log Changeset: r83488:4a28028053f5 Date: 2016-04-01 11:54 +0200 http://bitbucket.org/pypy/pypy/changeset/4a28028053f5/ Log:do not release gil for two logger functions. they are called in @rgc.no_release_gil diff --git a/rpython/jit/metainterp/jitlog.py b/rpython/jit/metainterp/jitlog.py --- a/rpython/jit/metainterp/jitlog.py +++ b/rpython/jit/metainterp/jitlog.py @@ -91,7 +91,7 @@ def log_jit_counter(self, struct): if not self.cintf.jitlog_enabled(): -return EMPTY_TRACE_LOG +return le_addr = encode_le_addr(struct.number) # not an address (but a number) but it is a machine word le_count = encode_le_addr(struct.i) 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 @@ -63,9 +63,11 @@ [], lltype.Void, compilation_info=eci) jitlog_write_marked = rffi.llexternal("jitlog_write_marked", [rffi.INT, rffi.CCHARP, rffi.INT], - lltype.Void, compilation_info=eci) + lltype.Void, compilation_info=eci, + releasegil=False) jitlog_enabled = rffi.llexternal("jitlog_enabled", [], rffi.INT, -compilation_info=eci) + compilation_info=eci, + releasegil=False) jitlog_teardown = rffi.llexternal("jitlog_teardown", [], lltype.Void, compilation_info=eci) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy new-jit-log: another releasegil=False
Author: Richard Plangger Branch: new-jit-log Changeset: r83489:0edef2d07438 Date: 2016-04-01 12:42 +0200 http://bitbucket.org/pypy/pypy/changeset/0edef2d07438/ Log:another releasegil=False 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 @@ -60,7 +60,8 @@ jitlog_init = rffi.llexternal("jitlog_init", [rffi.INT, rffi.CCHARP], rffi.CCHARP, compilation_info=eci) jitlog_try_init_using_env = rffi.llexternal("jitlog_try_init_using_env", - [], lltype.Void, compilation_info=eci) + [], lltype.Void, compilation_info=eci, + releasegil=False) jitlog_write_marked = rffi.llexternal("jitlog_write_marked", [rffi.INT, rffi.CCHARP, rffi.INT], lltype.Void, compilation_info=eci, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] benchmarks default: add the ability to number the counts
Author: fijal Branch: Changeset: r350:b75559ef571b Date: 2016-04-01 13:48 +0200 http://bitbucket.org/pypy/benchmarks/changeset/b75559ef571b/ Log:add the ability to number the counts diff --git a/warmup/pypy-graph-alloc-removal.py b/warmup/pypy-graph-alloc-removal.py --- a/warmup/pypy-graph-alloc-removal.py +++ b/warmup/pypy-graph-alloc-removal.py @@ -43,4 +43,8 @@ remover.remove_mallocs_once(g) return time.time() - start -main(graph, 100) +if len(sys.argv) > 2: +count = int(sys.argv[1]) +else: +count = 100 +main(graph, count) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] benchmarks default: improve
Author: fijal Branch: Changeset: r351:59290b59a24e Date: 2016-04-01 13:49 +0200 http://bitbucket.org/pypy/benchmarks/changeset/59290b59a24e/ Log:improve diff --git a/warmup/pypy-graph-alloc-removal.py b/warmup/pypy-graph-alloc-removal.py --- a/warmup/pypy-graph-alloc-removal.py +++ b/warmup/pypy-graph-alloc-removal.py @@ -43,7 +43,7 @@ remover.remove_mallocs_once(g) return time.time() - start -if len(sys.argv) > 2: +if len(sys.argv) >= 2: count = int(sys.argv[1]) else: count = 100 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-ext: fix strategy for zip()
Author: mattip Branch: cpyext-ext Changeset: r83496:bcaba584080e Date: 2016-04-01 16:48 +0300 http://bitbucket.org/pypy/pypy/changeset/bcaba584080e/ Log:fix strategy for zip() diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -321,16 +321,16 @@ raise NotImplementedError def getitems_bytes(self, w_list): -raise NotImplementedError +return None def getitems_unicode(self, w_list): -raise NotImplementedError +return None def getitems_int(self, w_list): -raise NotImplementedError +return None def getitems_float(self, w_list): -raise NotImplementedError +return None def getstorage_copy(self, w_list): raise NotImplementedError ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-ext: add missing methods, randomly revert some to ObjectStrategy when called, raise on the rest
Author: mattip Branch: cpyext-ext Changeset: r83494:ab7f77f250ba Date: 2016-03-31 21:20 +0300 http://bitbucket.org/pypy/pypy/changeset/ab7f77f250ba/ Log:add missing methods, randomly revert some to ObjectStrategy when called, raise on the rest diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -90,10 +90,10 @@ """ if isinstance(w_obj, listobject.W_ListObject): cpy_strategy = space.fromcache(CPyListStrategy) -if w_obj.strategy is not cpy_strategy: -raise OperationError(space.w_TypeError, space.wrap( -'PySequence_Fast_ITEMS called but object is not the result of PySequence_Fast')) -return w_obj.get_raw_items() # asserts it's a cpyext strategy +if w_obj.strategy is cpy_strategy: +return w_obj.get_raw_items() # asserts it's a cpyext strategy +raise OperationError(space.w_TypeError, space.wrap( +'PySequence_Fast_ITEMS called but object is not the result of PySequence_Fast')) @cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) def PySequence_GetSlice(space, w_obj, start, end): @@ -262,13 +262,108 @@ def getslice(self, w_list, start, stop, step, length): #storage = self.unerase(w_list.lstorage) -raise oefmt(w_list.space.w_NotImplementedError, -"settting a slice of a PySequence_Fast is not supported") +raise OperationError(w_list.space.w_NotImplementedError, w_list.space.wrap( +"settting a slice of a PySequence_Fast is not supported")) + +def getitems(self, w_list): +# called when switching list strategy, so convert storage +storage = self.unerase(w_list.lstorage) +retval = [None] * storage._length +for i in range(storage._length): +retval[i] = from_ref(w_list.space, storage._elems[i]) +return retval + +#-- +# all these methods fail or switch strategy and then call ListObjectStrategy's method + +def getitems_fixedsize(self, w_list): +raise NotImplementedError def setslice(self, w_list, start, stop, step, length): #storage = self.unerase(w_list.lstorage) -raise oefmt(w_list.space.w_NotImplementedError, -"settting a slice of a PySequence_Fast is not supported") +raise NotImplementedError + +def get_sizehint(self): +return -1 + +def init_from_list_w(self, w_list, list_w): +raise NotImplementedError + +def clone(self, w_list): +raise NotImplementedError + +def copy_into(self, w_list, w_other): +raise NotImplementedError + +def _resize_hint(self, w_list, hint): +raise NotImplementedError + +def find(self, w_list, w_item, start, stop): +raise NotImplementedError + +def getitems_copy(self, w_list): +raise NotImplementedError + +def getitems_bytes(self, w_list): +raise NotImplementedError + +def getitems_unicode(self, w_list): +raise NotImplementedError + +def getitems_int(self, w_list): +raise NotImplementedError + +def getitems_float(self, w_list): +raise NotImplementedError + +def getstorage_copy(self, w_list): +raise NotImplementedError + +def append(self, w_list, w_item): +w_list.switch_to_object_strategy() +w_list.strategy.append(w_list, w_item) + +def mul(self, w_list, times): +raise NotImplementedError + +def inplace_mul(self, w_list, times): +raise NotImplementedError + +def deleteslice(self, w_list, start, step, slicelength): +raise NotImplementedError + +def pop(self, w_list, index): +w_list.switch_to_object_strategy() +w_list.strategy.pop(w_list, index) + +def pop_end(self, w_list): +w_list.switch_to_object_strategy() +w_list.strategy.pop_end(w_list) + +def insert(self, w_list, index, w_item): +w_list.switch_to_object_strategy() +w_list.strategy.insert(w_list, index, w_item) + +def extend(self, w_list, w_any): +w_list.switch_to_object_strategy() +w_list.strategy.extend(w_list, w_any) + +def _extend_from_list(self, w_list, w_other): +raise NotImplementedError + +def _extend_from_iterable(self, w_list, w_iterable): +raise NotImplementedError + +def reverse(self, w_list): +w_list.switch_to_object_strategy() +w_list.strategy.reverse(w_list) + +def sort(self, w_list, reverse): +w_list.switch_to_object_strategy() +w_list.descr_sort(w_list.space, reverse=reverse) + +def is_empty_strategy(self): +return False PyObjectList = lltype.Ptr(lltype.Array(PyObject, hints={'nolength': True})) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.o
[pypy-commit] pypy cpyext-ext: add missing methods, test
Author: mattip Branch: cpyext-ext Changeset: r83495:8f34e1689105 Date: 2016-04-01 10:01 +0300 http://bitbucket.org/pypy/pypy/changeset/8f34e1689105/ Log:add missing methods, test diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -1,12 +1,13 @@ -from rpython.rlib import rerased +from rpython.rlib import rerased, jit from pypy.interpreter.error import OperationError, oefmt -from pypy.objspace.std.listobject import ListStrategy +from pypy.objspace.std.listobject import ( +ListStrategy, UNROLL_CUTOFF, W_ListObject, ObjectListStrategy) from pypy.module.cpyext.api import ( cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t, PyObject, PyObjectP) from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.objspace.std import listobject, tupleobject +from pypy.objspace.std import tupleobject from pypy.module.cpyext.tupleobject import PyTuple_Check, PyTuple_SetItem from pypy.module.cpyext.object import Py_IncRef, Py_DecRef @@ -44,12 +45,12 @@ which case o is returned. Use PySequence_Fast_GET_ITEM() to access the members of the result. Returns NULL on failure. If the object is not a sequence, raises TypeError with m as the message text.""" -if isinstance(w_obj, listobject.W_ListObject): +if isinstance(w_obj, W_ListObject): # make sure we can return a borrowed obj from PySequence_Fast_GET_ITEM w_obj.convert_to_cpy_strategy(space) return w_obj try: -return listobject.W_ListObject.newlist_cpyext(space, space.listview(w_obj)) +return W_ListObject.newlist_cpyext(space, space.listview(w_obj)) except OperationError: raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m))) @@ -58,7 +59,7 @@ """Return the ith element of o, assuming that o was returned by PySequence_Fast(), o is not NULL, and that i is within bounds. """ -if isinstance(w_obj, listobject.W_ListObject): +if isinstance(w_obj, W_ListObject): return w_obj.getitem(index) elif isinstance(w_obj, tupleobject.W_TupleObject): return w_obj.wrappeditems[index] @@ -72,7 +73,7 @@ gotten by calling PySequence_Size() on o, but PySequence_Fast_GET_SIZE() is faster because it can assume o is a list or tuple.""" -if isinstance(w_obj, listobject.W_ListObject): +if isinstance(w_obj, W_ListObject): return w_obj.length() elif isinstance(w_obj, tupleobject.W_TupleObject): return len(w_obj.wrappeditems) @@ -88,7 +89,7 @@ So, only use the underlying array pointer in contexts where the sequence cannot change. """ -if isinstance(w_obj, listobject.W_ListObject): +if isinstance(w_obj, W_ListObject): cpy_strategy = space.fromcache(CPyListStrategy) if w_obj.strategy is cpy_strategy: return w_obj.get_raw_items() # asserts it's a cpyext strategy @@ -276,9 +277,20 @@ #-- # all these methods fail or switch strategy and then call ListObjectStrategy's method +@jit.unroll_safe +def getitems_unroll(self, w_list): +storage = self.unerase(w_list.lstorage) +retval = [None] * storage._length +for i in range(storage._length): +retval[i] = from_ref(w_list.space, storage._elems[i]) +return retval + +@jit.look_inside_iff(lambda self, w_list: +jit.loop_unrolling_heuristic(w_list, w_list.length(), + UNROLL_CUTOFF)) def getitems_fixedsize(self, w_list): -raise NotImplementedError - +return self.getitems_unroll(w_list) + def setslice(self, w_list, start, stop, step, length): #storage = self.unerase(w_list.lstorage) raise NotImplementedError @@ -290,8 +302,12 @@ raise NotImplementedError def clone(self, w_list): -raise NotImplementedError - +storage = w_list.lstorage # lstorage is tuple, no need to clone +w_clone = W_ListObject.from_storage_and_strategy(self.space, storage, + self) +w_clone.switch_to_object_strategy() +return w_clone + def copy_into(self, w_list, w_other): raise NotImplementedError diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py --- a/pypy/module/cpyext/test/test_sequence.py +++ b/pypy/module/cpyext/test/test_sequence.py @@ -178,6 +178,19 @@ assert space.int_w(space.len(w_l)) == 5 assert space.int_w(space.getitem(w_l, w(0))) == 0 +api.PySequence_Fast(w_l, "foo") # converts +w_t = space.wrap(space.fixedview(w_l)) +assert space.int_w(space.len(w_t)) == 5 +assert space.int_w(space.getitem(w_t, w(0)
[pypy-commit] pypy cpyext-ext: refactor error checking to make sure the strategy is correct
Author: mattip Branch: cpyext-ext Changeset: r83493:eab8aff36a9f Date: 2016-03-31 19:29 +0300 http://bitbucket.org/pypy/pypy/changeset/eab8aff36a9f/ Log:refactor error checking to make sure the strategy is correct diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -59,11 +59,11 @@ PySequence_Fast(), o is not NULL, and that i is within bounds. """ if isinstance(w_obj, listobject.W_ListObject): -w_res = w_obj.getitem(index) -else: -assert isinstance(w_obj, tupleobject.W_TupleObject) -w_res = w_obj.wrappeditems[index] -return w_res # borrowed ref +return w_obj.getitem(index) +elif isinstance(w_obj, tupleobject.W_TupleObject): +return w_obj.wrappeditems[index] +raise OperationError(space.w_TypeError, space.wrap( +'PySequence_Fast_GET_ITEM called but object is not a list or sequence')) @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) def PySequence_Fast_GET_SIZE(space, w_obj): @@ -74,8 +74,10 @@ or tuple.""" if isinstance(w_obj, listobject.W_ListObject): return w_obj.length() -assert isinstance(w_obj, tupleobject.W_TupleObject) -return len(w_obj.wrappeditems) +elif isinstance(w_obj, tupleobject.W_TupleObject): +return len(w_obj.wrappeditems) +raise OperationError(space.w_TypeError, space.wrap( +'PySequence_Fast_GET_SIZE called but object is not a list or sequence')) @cpython_api([PyObject], PyObjectP) def PySequence_Fast_ITEMS(space, w_obj): @@ -86,8 +88,12 @@ So, only use the underlying array pointer in contexts where the sequence cannot change. """ -assert isinstance(w_obj, listobject.W_ListObject) -return w_obj.get_raw_items() # asserts it's a cpyext strategy +if isinstance(w_obj, listobject.W_ListObject): +cpy_strategy = space.fromcache(CPyListStrategy) +if w_obj.strategy is not cpy_strategy: +raise OperationError(space.w_TypeError, space.wrap( +'PySequence_Fast_ITEMS called but object is not the result of PySequence_Fast')) +return w_obj.get_raw_items() # asserts it's a cpyext strategy @cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) def PySequence_GetSlice(space, w_obj, start, end): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-ext: test, implement more strategy methods, remove methods implemented in base class
Author: mattip Branch: cpyext-ext Changeset: r83497:c945e9acf8f8 Date: 2016-04-01 17:03 +0300 http://bitbucket.org/pypy/pypy/changeset/c945e9acf8f8/ Log:test, implement more strategy methods, remove methods implemented in base class diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -320,18 +320,6 @@ def getitems_copy(self, w_list): raise NotImplementedError -def getitems_bytes(self, w_list): -return None - -def getitems_unicode(self, w_list): -return None - -def getitems_int(self, w_list): -return None - -def getitems_float(self, w_list): -return None - def getstorage_copy(self, w_list): raise NotImplementedError @@ -339,11 +327,9 @@ w_list.switch_to_object_strategy() w_list.strategy.append(w_list, w_item) -def mul(self, w_list, times): -raise NotImplementedError - def inplace_mul(self, w_list, times): -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy.inplace_mul(w_list, times) def deleteslice(self, w_list, start, step, slicelength): raise NotImplementedError diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py --- a/pypy/module/cpyext/test/test_sequence.py +++ b/pypy/module/cpyext/test/test_sequence.py @@ -190,6 +190,14 @@ w_sum = space.add(w_l, w_l) assert space.int_w(space.len(w_sum)) == 10 +api.PySequence_Fast(w_l, "foo") # converts +w_prod = space.mul(w_l, space.wrap(2)) +assert space.int_w(space.len(w_prod)) == 10 + +api.PySequence_Fast(w_l, "foo") # converts +w_l.inplace_mul(2) +assert space.int_w(space.len(w_l)) == 10 + class XAppTestSequenceObject(AppTestCpythonExtensionBase): def test_sequenceobject(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-ext: test some list methods
Author: mattip Branch: cpyext-ext Changeset: r83492:4ef5f2c2ab24 Date: 2016-03-31 19:28 +0300 http://bitbucket.org/pypy/pypy/changeset/4ef5f2c2ab24/ Log:test some list methods diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py --- a/pypy/module/cpyext/test/test_sequence.py +++ b/pypy/module/cpyext/test/test_sequence.py @@ -164,6 +164,19 @@ space.setitem(w_l, space.wrap(1), space.wrap(13)) assert space.int_w(space.getitem(w_l, space.wrap(1))) == 13 +def test_manipulations(self, space, api): +w = space.wrap +w_l = w([1, 2, 3, 4]) + +api.PySequence_Fast(w_l, "foo") # converts +space.call_method(w_l, 'insert', w(0), w(0)) +assert space.int_w(space.len(w_l)) == 5 +assert space.int_w(space.getitem(w_l, w(3))) == 3 + +api.PySequence_Fast(w_l, "foo") # converts +space.call_method(w_l, 'sort') +assert space.int_w(space.len(w_l)) == 5 +assert space.int_w(space.getitem(w_l, w(0))) == 0 class XAppTestSequenceObject(AppTestCpythonExtensionBase): def test_sequenceobject(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy jit-constptr-2: x86-32 support
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83491:fd234418525e Date: 2016-04-01 16:14 +0200 http://bitbucket.org/pypy/pypy/changeset/fd234418525e/ Log:x86-32 support diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -4,7 +4,7 @@ from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite, gcreftracer from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, -DEBUG_COUNTER, debug_bridge) +DEBUG_COUNTER) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import (Const, VOID, ConstInt) @@ -523,10 +523,10 @@ looptoken.number, loopname, r_uint(rawstart + looppos), r_uint(rawstart + size_excluding_failure_stuff), -r_uint(rawstart))) -debug_print(" gc table: 0x%x" % r_uint(rawstart)) +r_uint(rawstart + functionpos))) +debug_print(" gc table: 0x%x" % r_uint(self.gc_table_addr)) debug_print(" function: 0x%x" % r_uint(rawstart + functionpos)) -debug_print(" loop: 0x%x" % r_uint(rawstart + looppos)) +debug_print(" resops: 0x%x" % r_uint(rawstart + looppos)) debug_print(" failures: 0x%x" % r_uint(rawstart + size_excluding_failure_stuff)) debug_print("end: 0x%x" % r_uint(rawstart + full_size)) @@ -591,7 +591,16 @@ self.patch_gcref_table(original_loop_token, rawstart) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, rawstart) -debug_bridge(descr_number, rawstart, codeendpos) +debug_start("jit-backend-addr") +debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % +(r_uint(descr_number), r_uint(rawstart + startpos), +r_uint(rawstart + codeendpos))) +debug_print(" gc table: 0x%x" % r_uint(self.gc_table_addr)) +debug_print("jump target: 0x%x" % r_uint(rawstart + startpos)) +debug_print(" resops: 0x%x" % r_uint(rawstart + bridgestartpos)) +debug_print(" failures: 0x%x" % r_uint(rawstart + codeendpos)) +debug_print("end: 0x%x" % r_uint(rawstart + fullsize)) +debug_stop("jit-backend-addr") self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard self.patch_jump_for_descr(faildescr, rawstart + startpos) @@ -667,18 +676,32 @@ self.patch_jump_for_descr(faildescr, rawstart) def reserve_gcref_table(self, allgcrefs): -assert IS_X86_64, "XXX" gcref_table_size = len(allgcrefs) * WORD -# align to a multiple of 16 -gcref_table_size = (gcref_table_size + 15) & ~15 -mc = self.mc -assert mc.get_relative_pos() == 0 -for i in range(gcref_table_size): -mc.writechar('\x00') +if IS_X86_64: +# align to a multiple of 16 and reserve space at the beginning +# of the machine code for the gc table. This lets us write +# machine code with relative addressing (%rip - constant). +gcref_table_size = (gcref_table_size + 15) & ~15 +mc = self.mc +assert mc.get_relative_pos() == 0 +for i in range(gcref_table_size): +mc.writechar('\x00') +elif IS_X86_32: +# allocate the gc table right now. This lets us write +# machine code with absolute 32-bit addressing. +self.gc_table_addr = self.datablockwrapper.malloc_aligned( +gcref_table_size, alignment=WORD) +# self.setup_gcrefs_list(allgcrefs) def patch_gcref_table(self, looptoken, rawstart): -assert IS_X86_64, "XXX" +if IS_X86_64: +# the gc table is at the start of the machine code +self.gc_table_addr = rawstart +elif IS_X86_32: +# the gc table was already allocated by reserve_gcref_table() +rawstart = self.gc_table_addr +# tracer = gcreftracer.make_gcref_tracer(rawstart, self._allgcrefs) gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken) gcreftracers.append(tracer)# keepalive @@ -1396,18 +1419,27 @@ def _patch_load_from_gc_table(self, index): # must be called immediately after a "p"-mode instruction -# has been emitted +# has been emitted. 64-bit mode only. +assert IS_X86_64 address_in_buffer = index * WORD # at the start of the buffer p_location = self.mc.
[pypy-commit] pypy jit-constptr-2: Kill this test, supersceded by tests in test_rewrite
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83498:9f37768db82d Date: 2016-04-01 16:33 +0200 http://bitbucket.org/pypy/pypy/changeset/9f37768db82d/ Log:Kill this test, supersceded by tests in test_rewrite diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -196,31 +196,6 @@ assert is_valid_int(wbdescr.jit_wb_if_flag_byteofs) assert is_valid_int(wbdescr.jit_wb_if_flag_singlebyte) -def test_record_constptrs(self): -class MyFakeCPU(object): -def cast_adr_to_int(self, adr): -assert adr == "some fake address" -return 43 -class MyFakeGCRefList(object): -def get_address_of_gcref(self, s_gcref1): -assert s_gcref1 == s_gcref -return "some fake address" -S = lltype.GcStruct('S') -s = lltype.malloc(S) -s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) -v_random_box = InputArgRef() -operations = [ -ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)]), -] -gc_ll_descr = self.gc_ll_descr -gc_ll_descr.gcrefs = MyFakeGCRefList() -gcrefs = [] -operations = get_deep_immutable_oplist(operations) -operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations, - gcrefs) -assert operations2 == operations -assert gcrefs == [s_gcref] - class TestFrameworkMiniMark(TestFramework): gc = 'minimark' ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy new-jit-log: exposed enable_jitlog in module _vmprof, JITLOG env variable now controls the jitlog output file (bugfix), setup_once is now called while initializing the metainterp_sd
Author: Richard Plangger Branch: new-jit-log Changeset: r83499:f42dc412ebd9 Date: 2016-04-01 17:19 +0200 http://bitbucket.org/pypy/pypy/changeset/f42dc412ebd9/ Log:exposed enable_jitlog in module _vmprof, JITLOG env variable now controls the jitlog output file (bugfix), setup_once is now called while initializing the metainterp_sd diff --git a/pypy/module/_vmprof/__init__.py b/pypy/module/_vmprof/__init__.py --- a/pypy/module/_vmprof/__init__.py +++ b/pypy/module/_vmprof/__init__.py @@ -10,6 +10,7 @@ interpleveldefs = { 'enable': 'interp_vmprof.enable', +'enable_jitlog': 'interp_vmprof.enable_jitlog', 'disable': 'interp_vmprof.disable', 'write_all_code_objects': 'interp_vmprof.write_all_code_objects', 'VMProfError': 'space.fromcache(interp_vmprof.Cache).w_VMProfError', diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py --- a/pypy/module/_vmprof/interp_vmprof.py +++ b/pypy/module/_vmprof/interp_vmprof.py @@ -69,6 +69,14 @@ except rvmprof.VMProfError, e: raise VMProfError(space, e) +@unwrap_spec(fileno=int) +def enable_jitlog(space, fileno): +""" Enable PyPy's logging facility. """ +try: +rvmprof.enable_jitlog(fileno) +except rvmprof.VMProfError, e: +raise VMProfError(space, e) + def write_all_code_objects(space): """ Needed on cpython, just empty function here """ diff --git a/rpython/jit/backend/x86/test/test_jitlog.py b/rpython/jit/backend/x86/test/test_jitlog.py --- a/rpython/jit/backend/x86/test/test_jitlog.py +++ b/rpython/jit/backend/x86/test/test_jitlog.py @@ -1,4 +1,5 @@ import re +import os from rpython.rlib import debug from rpython.jit.tool.oparser import pure_parse from rpython.jit.metainterp import logger @@ -15,13 +16,34 @@ class TestLogger(Jit386Mixin): -def test_log_loop(self): -myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res']) +def test_explicit_enable(self): vmprof = rvmprof.VMProf() fileno, name = tempfile.mkstemp() +self.run_sample_loop(lambda: vmprof.enable_jitlog(fileno)) +assert os.path.exists(name) +with open(name, 'rb') as fd: +# check the file header +assert fd.read(3) == '\x23\xfe\xaf' +assert len(fd.read()) > 0 +print(name) + +def test_venv(self): +fileno, name = tempfile.mkstemp() +os.environ["JITLOG"] = name +self.run_sample_loop(None) +assert os.path.exists(name) +with open(name, 'rb') as fd: +# check the file header +assert fd.read(3) == '\x23\xfe\xaf' +assert len(fd.read()) > 0 +print(name) + +def run_sample_loop(self, func): +myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res']) def f(x, y): res = 0 -vmprof.enable(fileno, 0.1) +if func: +func() while y > 0: myjitdriver.can_enter_jit(x=x, y=y, res=res) myjitdriver.jit_merge_point(x=x, y=y, res=res) @@ -34,4 +56,3 @@ return res res = self.meta_interp(f, [6, 20]) self.check_trace_count(2) -print(name) diff --git a/rpython/jit/metainterp/jitlog.py b/rpython/jit/metainterp/jitlog.py --- a/rpython/jit/metainterp/jitlog.py +++ b/rpython/jit/metainterp/jitlog.py @@ -29,6 +29,8 @@ MARK_JIT_BRIDGE_COUNTER = 0x21 MARK_JIT_ENTRY_COUNTER = 0x22 +MARK_JITLOG_HEADER = 0x23 + IS_32_BIT = sys.maxint == 2**31-1 @always_inline @@ -69,10 +71,16 @@ self.is_setup = False def setup_once(self): +if self.is_setup: +return self.is_setup = True self.cintf.jitlog_try_init_using_env() if not self.cintf.jitlog_enabled(): return + +header = encode_le_16bit(0xaffe) +self._write_marked(MARK_JITLOG_HEADER, header) + count = len(resoperations.opname) mark = MARK_RESOP_META for opnum, opname in resoperations.opname.items(): @@ -81,12 +89,11 @@ def teardown(self): self.cintf.jitlog_teardown() +self.is_setup = False def _write_marked(self, mark, line): if not we_are_translated(): assert self.cintf.jitlog_enabled() -if not self.is_setup: -self.setup_once() self.cintf.jitlog_write_marked(mark, line, len(line)) def log_jit_counter(self, struct): 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 @@ -1819,6 +1819,7 @@ def _setup_once(self): """Runtime setup needed by the various components of the JIT.""" if not self.globaldata.initialized: +self.jitlog.setup_once() debug_print(self.jit_starting_line) self.cpu.setup_once() if not s
[pypy-commit] pypy jit-constptr-2: Boehm support: the custom tracer won't work there, and the memory may
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83500:aa7ba84109cb Date: 2016-04-01 18:17 +0200 http://bitbucket.org/pypy/pypy/changeset/aa7ba84109cb/ Log:Boehm support: the custom tracer won't work there, and the memory may not be scanned by Boehm itself diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -345,6 +345,13 @@ arraydescr.itemsize, arraydescr.lendescr.offset) +def make_gcref_tracer(self, array_base_addr, gcrefs): +from rpython.jit.backend.llsupport import gcreftracer +return gcreftracer.make_boehm_tracer(array_base_addr, gcrefs) + +def clear_gcref_tracer(self, tracer): +pass# nothing needed + # # All code below is for the hybrid or minimark GC @@ -755,6 +762,13 @@ p = rffi.cast(rffi.CCHARP, p) return (ord(p[0]) & IS_OBJECT_FLAG) != 0 +def make_gcref_tracer(self, array_base_addr, gcrefs): +from rpython.jit.backend.llsupport import gcreftracer +return gcreftracer.make_framework_tracer(array_base_addr, gcrefs) + +def clear_gcref_tracer(self, tracer): +tracer.array_length = 0 + # def get_ll_description(gcdescr, translator=None, rtyper=None): diff --git a/rpython/jit/backend/llsupport/gcreftracer.py b/rpython/jit/backend/llsupport/gcreftracer.py --- a/rpython/jit/backend/llsupport/gcreftracer.py +++ b/rpython/jit/backend/llsupport/gcreftracer.py @@ -21,7 +21,7 @@ i += 1 lambda_gcrefs_trace = lambda: gcrefs_trace -def make_gcref_tracer(array_base_addr, gcrefs): +def make_framework_tracer(array_base_addr, gcrefs): # careful about the order here: the allocation of the GCREFTRACER # can trigger a GC. So we must write the gcrefs into the raw # array only afterwards... @@ -39,3 +39,11 @@ llop.gc_writebarrier(lltype.Void, tr) # --no GC until here-- return tr + +def make_boehm_tracer(array_base_addr, gcrefs): +# copy the addresses, but return 'gcrefs' as the object that must be +# kept alive +for i in range(len(gcrefs)): +p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD) +p[0] = rffi.cast(lltype.Signed, gcrefs[i]) +return gcrefs diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -251,7 +251,7 @@ if tracers is not None: compiled_loop_token.asmmemmgr_gcreftracers = None for tracer in tracers: -tracer.array_length = 0 +self.gc_ll_descr.clear_gcref_tracer(tracer) # then free all blocks of code and raw data blocks = compiled_loop_token.asmmemmgr_blocks if blocks is not None: diff --git a/rpython/jit/backend/llsupport/test/test_gcreftracer.py b/rpython/jit/backend/llsupport/test/test_gcreftracer.py --- a/rpython/jit/backend/llsupport/test/test_gcreftracer.py +++ b/rpython/jit/backend/llsupport/test/test_gcreftracer.py @@ -1,6 +1,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.jit.backend.llsupport.gcreftracer import GCREFTRACER, gcrefs_trace -from rpython.jit.backend.llsupport.gcreftracer import make_gcref_tracer +from rpython.jit.backend.llsupport.gcreftracer import make_framework_tracer +from rpython.jit.backend.llsupport.gcreftracer import make_boehm_tracer class FakeGC: @@ -29,13 +30,24 @@ assert gc.called[i] == rffi.cast(llmemory.Address, base + i * WORD) lltype.free(a, flavor='raw') -def test_make_gcref_tracer(): +def test_make_framework_tracer(): a = lltype.malloc(rffi.CArray(lltype.Signed), 3, flavor='raw') base = rffi.cast(lltype.Signed, a) -tr = make_gcref_tracer(base, [123, 456, 789]) +tr = make_framework_tracer(base, [123, 456, 789]) assert a[0] == 123 assert a[1] == 456 assert a[2] == 789 assert tr.array_base_addr == base assert tr.array_length == 3 lltype.free(a, flavor='raw') + +def test_make_boehm_tracer(): +a = lltype.malloc(rffi.CArray(lltype.Signed), 3, flavor='raw') +base = rffi.cast(lltype.Signed, a) +lst = [123, 456, 789] +tr = make_boehm_tracer(base, lst) +assert a[0] == 123 +assert a[1] == 456 +assert a[2] == 789 +assert tr is lst +lltype.free(a, flavor='raw') diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2,7 +2,7 @@ import os import py -from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite, gcreftracer +from rpython.jit.backend.llsupport import symbolic, jitfr
[pypy-commit] pypy jit-constptr-2: (untested) ARM support
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83502:646421afc5c5 Date: 2016-04-01 19:14 +0200 http://bitbucket.org/pypy/pypy/changeset/646421afc5c5/ Log:(untested) ARM support diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -14,7 +14,7 @@ CoreRegisterManager, check_imm_arg, VFPRegisterManager, operations as regalloc_operations) from rpython.jit.backend.llsupport import jitframe, rewrite -from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, debug_bridge, BaseAssembler +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, BaseAssembler from rpython.jit.backend.llsupport.regalloc import get_scale, valid_addressing_size from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken @@ -481,8 +481,9 @@ def generate_quick_failure(self, guardtok): startpos = self.mc.currpos() -fail_descr, target = self.store_info_on_descr(startpos, guardtok) -self.regalloc_push(imm(fail_descr)) +faildescrindex, target = self.store_info_on_descr(startpos, guardtok) +self.load_from_gc_table(r.ip.value, faildescrindex) +self.regalloc_push(r.ip) self.push_gcmap(self.mc, gcmap=guardtok.gcmap, push=True) self.mc.BL(target) return startpos @@ -596,20 +597,22 @@ frame_info = self.datablockwrapper.malloc_aligned( jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) -clt.allgcrefs = [] clt.frame_info.clear() # for now if log: operations = self._inject_debugging_code(looptoken, operations, 'e', looptoken.number) +regalloc = Regalloc(assembler=self) +allgcrefs = [] +operations = regalloc.prepare_loop(inputargs, operations, looptoken, + allgcrefs) +self.reserve_gcref_table(allgcrefs) +functionpos = self.mc.get_relative_pos() + self._call_header_with_stack_check() self._check_frame_depth_debug(self.mc) -regalloc = Regalloc(assembler=self) -operations = regalloc.prepare_loop(inputargs, operations, looptoken, - clt.allgcrefs) - loop_head = self.mc.get_relative_pos() looptoken._ll_loop_code = loop_head # @@ -620,9 +623,11 @@ self.write_pending_failure_recoveries() +full_size = self.mc.get_relative_pos() rawstart = self.materialize_loop(looptoken) -looptoken._function_addr = looptoken._ll_function_addr = rawstart +looptoken._ll_function_addr = rawstart + functionpos +self.patch_gcref_table(looptoken, rawstart) self.process_pending_guards(rawstart) self.fixup_target_tokens(rawstart) @@ -641,7 +646,13 @@ looptoken.number, loopname, r_uint(rawstart + loop_head), r_uint(rawstart + size_excluding_failure_stuff), -r_uint(rawstart))) +r_uint(rawstart + functionpos))) +debug_print(" gc table: 0x%x" % r_uint(rawstart)) +debug_print(" function: 0x%x" % r_uint(rawstart + functionpos)) +debug_print(" resops: 0x%x" % r_uint(rawstart + loop_head)) +debug_print(" failures: 0x%x" % r_uint(rawstart + + size_excluding_failure_stuff)) +debug_print("end: 0x%x" % r_uint(rawstart + full_size)) debug_stop("jit-backend-addr") return AsmInfo(ops_offset, rawstart + loop_head, @@ -678,27 +689,43 @@ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) regalloc = Regalloc(assembler=self) -startpos = self.mc.get_relative_pos() +allgcrefs = [] operations = regalloc.prepare_bridge(inputargs, arglocs, operations, - self.current_clt.allgcrefs, + allgcrefs, self.current_clt.frame_info) +self.reserve_gcref_table(allgcrefs) +startpos = self.mc.get_relative_pos() self._check_frame_depth(self.mc, regalloc.get_gcmap()) +bridgestartpos = self.mc.get_relative_pos() frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() self.write_pending_failure_recoveries() +fullsize = self.mc.get_relative_pos() rawstart = self.materialize_loop(original_loop_token) +self.patch_gcref_table(original_loop_token, rawstart) self.pro
[pypy-commit] pypy jit-constptr-2: tweak
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83501:8245b29790fa Date: 2016-04-01 19:13 +0200 http://bitbucket.org/pypy/pypy/changeset/8245b29790fa/ Log:tweak diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1433,14 +1433,13 @@ return self.gc_table_addr + index * WORD def genop_load_from_gc_table(self, op, arglocs, resloc): -[loc] = arglocs -assert isinstance(loc, ImmedLoc) +index = op.getarg(0).getint() assert isinstance(resloc, RegLoc) if IS_X86_64: self.mc.MOV_rp(resloc.value, 0)# %rip-relative -self._patch_load_from_gc_table(loc.value) +self._patch_load_from_gc_table(index) elif IS_X86_32: -self.mc.MOV_rj(resloc.value, self._addr_from_gc_table(loc.value)) +self.mc.MOV_rj(resloc.value, self._addr_from_gc_table(index)) def genop_int_force_ge_zero(self, op, arglocs, resloc): self.mc.TEST(arglocs[0], arglocs[0]) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1135,7 +1135,10 @@ consider_same_as_i = _consider_same_as consider_same_as_r = _consider_same_as consider_same_as_f = _consider_same_as -consider_load_from_gc_table = _consider_same_as + +def consider_load_from_gc_table(self, op): +resloc = self.rm.force_allocate_reg(op) +self.perform(op, [], resloc) def consider_int_force_ge_zero(self, op): argloc = self.make_sure_var_in_reg(op.getarg(0)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy follow_symlinks: hg merge rposix-for-3
Author: Ronan Lamy Branch: follow_symlinks Changeset: r83503:1ca73c09051e Date: 2016-03-31 21:08 +0100 http://bitbucket.org/pypy/pypy/changeset/1ca73c09051e/ Log:hg merge rposix-for-3 diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -603,14 +603,44 @@ config = rffi_platform.configure(CConfig) DIRENT = config['DIRENT'] DIRENTP = lltype.Ptr(DIRENT) -c_opendir = external('opendir', [rffi.CCHARP], DIRP, - save_err=rffi.RFFI_SAVE_ERRNO) +c_opendir = external('opendir', +[rffi.CCHARP], DIRP, save_err=rffi.RFFI_SAVE_ERRNO) +c_fdopendir = external('fdopendir', +[rffi.INT], DIRP, save_err=rffi.RFFI_SAVE_ERRNO) # XXX macro=True is hack to make sure we get the correct kind of # dirent struct (which depends on defines) c_readdir = external('readdir', [DIRP], DIRENTP, macro=True, save_err=rffi.RFFI_FULL_ERRNO_ZERO) c_closedir = external('closedir', [DIRP], rffi.INT) +def _listdir(dirp): +result = [] +while True: +direntp = c_readdir(dirp) +if not direntp: +error = get_saved_errno() +break +namep = rffi.cast(rffi.CCHARP, direntp.c_d_name) +name = rffi.charp2str(namep) +if name != '.' and name != '..': +result.append(name) +c_closedir(dirp) +if error: +raise OSError(error, "readdir failed") +return result + +def fdlistdir(dirfd): +""" +Like listdir(), except that the directory is specified as an open +file descriptor. + +Note: fdlistdir() closes the file descriptor. +""" +dirp = c_fdopendir(dirfd) +if not dirp: +raise OSError(get_saved_errno(), "opendir failed") +return _listdir(dirp) + @replace_os_function('listdir') @specialize.argtype(0) def listdir(path): @@ -619,20 +649,7 @@ dirp = c_opendir(path) if not dirp: raise OSError(get_saved_errno(), "opendir failed") -result = [] -while True: -direntp = c_readdir(dirp) -if not direntp: -error = get_saved_errno() -break -namep = rffi.cast(rffi.CCHARP, direntp.c_d_name) -name = rffi.charp2str(namep) -if name != '.' and name != '..': -result.append(name) -c_closedir(dirp) -if error: -raise OSError(error, "readdir failed") -return result +return _listdir(dirp) else: # _WIN32 case traits = _preferred_traits(path) win32traits = make_win32_traits(traits) @@ -1801,6 +1818,26 @@ error = c_fchownat(dir_fd, path, owner, group, flag) handle_posix_error('fchownat', error) +if HAVE_FEXECVE: +c_fexecve = external('fexecve', +[rffi.INT, rffi.CCHARPP, rffi.CCHARPP], rffi.INT, +save_err=rffi.RFFI_SAVE_ERRNO) + +def fexecve(fd, args, env): +envstrs = [] +for item in env.iteritems(): +envstr = "%s=%s" % item +envstrs.append(envstr) + +# This list conversion already takes care of NUL bytes. +l_args = rffi.ll_liststr2charpp(args) +l_env = rffi.ll_liststr2charpp(envstrs) +c_fexecve(fd, l_args, l_env) + +rffi.free_charpp(l_env) +rffi.free_charpp(l_args) +raise OSError(get_saved_errno(), "execve failed") + if HAVE_LINKAT: c_linkat = external('linkat', [rffi.INT, rffi.CCHARP, rffi.INT, rffi.CCHARP, rffi.INT], rffi.INT) diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -11,6 +11,8 @@ return py.test.mark.skipif(not hasattr(rposix, funcname), reason="Requires rposix.%s()" % funcname) +win_only = py.test.mark.skipif("os.name != 'nt'") + class TestPosixFunction: def test_access(self): filename = str(udir.join('test_access.txt')) @@ -33,9 +35,8 @@ for value in times: assert isinstance(value, float) +@py.test.mark.skipif("not hasattr(os, 'getlogin')") def test_getlogin(self): -if not hasattr(os, 'getlogin'): -py.test.skip('posix specific function') try: expected = os.getlogin() except OSError, e: @@ -43,9 +44,8 @@ data = rposix.getlogin() assert data == expected +@win_only def test_utimes(self): -if os.name != 'nt': -py.test.skip('Windows specific feature') # Windows support centiseconds def f(fname, t1): os.utime(fname, (t1, t1)) @@ -55,15 +55,12 @@ t1 = 1159195039.25 compile(f, (str, float))(str(fname), t1) assert t1 == os.stat(str(fname)).st_mtime -if sys.version_info < (2, 7): -py.test.skip('requires Python 2.7') t1 = 50.0
[pypy-commit] pypy follow_symlinks: Separate implementations of execv() and execve() since their signature and validation logic differ
Author: Ronan Lamy Branch: follow_symlinks Changeset: r83505:9dc07d8a2654 Date: 2016-04-01 20:35 +0100 http://bitbucket.org/pypy/pypy/changeset/9dc07d8a2654/ Log:Separate implementations of execv() and execve() since their signature and validation logic differ diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1151,7 +1151,23 @@ path: path of executable file args: iterable of strings """ -execve(space, w_path, w_args, None) +command = space.fsencode_w(w_path) +try: +args_w = space.unpackiterable(w_args) +if len(args_w) < 1: +raise oefmt(space.w_ValueError, +"execv() arg 2 must not be empty") +args = [space.fsencode_w(w_arg) for w_arg in args_w] +except OperationError, e: +if not e.match(space, space.w_TypeError): +raise +raise oefmt(space.w_TypeError, +"execv() arg 2 must be an iterable of strings") +try: +os.execv(command, args) +except OSError as e: +raise wrap_oserror(space, e) + def _env2interp(space, w_env): env = {} @@ -1161,7 +1177,8 @@ env[space.fsencode_w(w_key)] = space.fsencode_w(w_value) return env -def execve(space, w_path, w_args, w_env): + +def execve(space, w_path, w_argv, w_environment): """execve(path, args, env) Execute a path with arguments and environment, replacing current process. @@ -1175,29 +1192,16 @@ If this functionality is unavailable, using it raises NotImplementedError. """ command = space.fsencode_w(w_path) +if not (space.isinstance_w(w_argv, space.w_list) +or space.isinstance_w(w_argv, space.w_tuple)): +raise oefmt(space.w_TypeError, +"execve: argv must be a tuple or a list") +args = [space.fsencode_w(w_arg) for w_arg in space.unpackiterable(w_argv)] +env = _env2interp(space, w_environment) try: -args_w = space.unpackiterable(w_args) -if len(args_w) < 1: -w_msg = space.wrap("execv() must have at least one argument") -raise OperationError(space.w_ValueError, w_msg) -args = [space.fsencode_w(w_arg) for w_arg in args_w] -except OperationError, e: -if not e.match(space, space.w_TypeError): -raise -msg = "execv() arg 2 must be an iterable of strings" -raise OperationError(space.w_TypeError, space.wrap(str(msg))) -# -if w_env is None:# when called via execv() above -try: -os.execv(command, args) -except OSError, e: -raise wrap_oserror(space, e) -else: -env = _env2interp(space, w_env) -try: -os.execve(command, args, env) -except OSError, e: -raise wrap_oserror(space, e) +os.execve(command, args, env) +except OSError, e: +raise wrap_oserror(space, e) @unwrap_spec(mode=int, path='fsencode') def spawnv(space, mode, path, w_args): diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -415,7 +415,6 @@ def test_execv_no_args(self): os = self.posix raises(ValueError, os.execv, "notepad", []) -raises(ValueError, os.execve, "notepad", [], {}) def test_execv_raising2(self): os = self.posix ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy follow_symlinks: Update execve() docstring
Author: Ronan Lamy Branch: follow_symlinks Changeset: r83504:befb634cf35b Date: 2016-03-31 21:20 +0100 http://bitbucket.org/pypy/pypy/changeset/befb634cf35b/ Log:Update execve() docstring diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1142,7 +1142,8 @@ def _exit(space, status): os._exit(status) -def execv(space, w_command, w_args): +def execv(space, w_path, w_args): + """ execv(path, args) Execute an executable path with arguments, replacing current process. @@ -1150,7 +1151,7 @@ path: path of executable file args: iterable of strings """ -execve(space, w_command, w_args, None) +execve(space, w_path, w_args, None) def _env2interp(space, w_env): env = {} @@ -1160,16 +1161,20 @@ env[space.fsencode_w(w_key)] = space.fsencode_w(w_value) return env -def execve(space, w_command, w_args, w_env): -""" execve(path, args, env) +def execve(space, w_path, w_args, w_env): +"""execve(path, args, env) Execute a path with arguments and environment, replacing current process. -path: path of executable file -args: iterable of arguments -env: dictionary of strings mapping to strings +path: path of executable file +args: tuple or list of arguments +env: dictionary of strings mapping to strings + +On some platforms, you may specify an open file descriptor for path; + execve will execute the program the file descriptor is open to. + If this functionality is unavailable, using it raises NotImplementedError. """ -command = space.fsencode_w(w_command) +command = space.fsencode_w(w_path) try: args_w = space.unpackiterable(w_args) if len(args_w) < 1: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy follow_symlinks: Allow path as file descriptor in execve()
Author: Ronan Lamy Branch: follow_symlinks Changeset: r83506:a64857baf5ce Date: 2016-04-01 20:55 +0100 http://bitbucket.org/pypy/pypy/changeset/a64857baf5ce/ Log:Allow path as file descriptor in execve() diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1191,7 +1191,6 @@ execve will execute the program the file descriptor is open to. If this functionality is unavailable, using it raises NotImplementedError. """ -command = space.fsencode_w(w_path) if not (space.isinstance_w(w_argv, space.w_list) or space.isinstance_w(w_argv, space.w_tuple)): raise oefmt(space.w_TypeError, @@ -1199,9 +1198,25 @@ args = [space.fsencode_w(w_arg) for w_arg in space.unpackiterable(w_argv)] env = _env2interp(space, w_environment) try: -os.execve(command, args, env) -except OSError, e: -raise wrap_oserror(space, e) +path = space.fsencode_w(w_path) +except OperationError: +if not rposix.HAVE_FEXECVE: +raise oefmt(space.w_TypeError, +"execve: illegal type for path argument") +if not space.isinstance_w(w_path, space.w_int): +raise oefmt(space.w_TypeError, +"argument should be string, bytes or integer, not %T", w_path) +# File descriptor case +fd = unwrap_fd(space, w_path) +try: +rposix.fexecve(fd, args, env) +except OSError as e: +raise wrap_oserror(space, e) +else: +try: +os.execve(path, args, env) +except OSError as e: +raise wrap_oserror(space, e) @unwrap_spec(mode=int, path='fsencode') def spawnv(space, mode, path, w_args): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy jit-constptr-2: fix(?)
Author: Armin Rigo Branch: jit-constptr-2 Changeset: r83507:af7d68248897 Date: 2016-04-02 00:09 +0200 http://bitbucket.org/pypy/pypy/changeset/af7d68248897/ Log:fix(?) diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -557,7 +557,7 @@ debug_stop('jit-backend-ops') def _call_header(self): -assert self.mc.currpos() == 0 +# there is the gc table before this point self.gen_func_prolog() def _call_header_with_stack_check(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-ext: finish all CPyListStrategy methods
Author: mattip Branch: cpyext-ext Changeset: r83508:29f300d480a2 Date: 2016-04-02 01:57 +0300 http://bitbucket.org/pypy/pypy/changeset/29f300d480a2/ Log:finish all CPyListStrategy methods diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -274,9 +274,6 @@ retval[i] = from_ref(w_list.space, storage._elems[i]) return retval -#-- -# all these methods fail or switch strategy and then call ListObjectStrategy's method - @jit.unroll_safe def getitems_unroll(self, w_list): storage = self.unerase(w_list.lstorage) @@ -291,9 +288,12 @@ def getitems_fixedsize(self, w_list): return self.getitems_unroll(w_list) +#-- +# all these methods fail or switch strategy and then call ListObjectStrategy's method + def setslice(self, w_list, start, stop, step, length): -#storage = self.unerase(w_list.lstorage) -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy.setslice(w_list, start, stop, step, length) def get_sizehint(self): return -1 @@ -309,16 +309,19 @@ return w_clone def copy_into(self, w_list, w_other): -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy.copy_into(w_list, w_other) def _resize_hint(self, w_list, hint): -raise NotImplementedError +pass def find(self, w_list, w_item, start, stop): -raise NotImplementedError +w_list.switch_to_object_strategy() +return w_list.strategy.find(w_list, w_item, start, stop) def getitems_copy(self, w_list): -raise NotImplementedError +w_list.switch_to_object_strategy() +return w_list.strategy.getitems_copy(w_list) def getstorage_copy(self, w_list): raise NotImplementedError @@ -332,7 +335,8 @@ w_list.strategy.inplace_mul(w_list, times) def deleteslice(self, w_list, start, step, slicelength): -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy.deleteslice(w_list, start, step, slicelength) def pop(self, w_list, index): w_list.switch_to_object_strategy() @@ -351,10 +355,12 @@ w_list.strategy.extend(w_list, w_any) def _extend_from_list(self, w_list, w_other): -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy._extend_from_list(w_list, w_other) def _extend_from_iterable(self, w_list, w_iterable): -raise NotImplementedError +w_list.switch_to_object_strategy() +w_list.strategy._extend_from_iterable(w_list, w_iterable) def reverse(self, w_list): w_list.switch_to_object_strategy() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit