[pypy-commit] pypy jit-constptr-2: translation fix for some tests

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83473:647c93899602
Date: 2016-04-01 00:56 +0200
http://bitbucket.org/pypy/pypy/changeset/647c93899602/

Log:translation fix for some tests

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -321,8 +321,8 @@
 # this case means between CALLs or unknown-size mallocs.
 #
 self.gcrefs_output_list = gcrefs_output_list
-self.gcrefs_map = r_dict(rd_eq, rd_hash)   # rdict {gcref: index}
-self.gcrefs_recently_loaded = {}
+self.gcrefs_map = None
+self.gcrefs_recently_loaded = None
 operations = self.remove_bridge_exception(operations)
 self._changed_op = None
 for i in range(len(operations)):
@@ -955,9 +955,11 @@
 def emit_label(self):
 self.emitting_an_operation_that_can_collect()
 self._known_lengths.clear()
-self.gcrefs_recently_loaded.clear()
+self.gcrefs_recently_loaded = None
 
 def _gcref_index(self, gcref):
+if self.gcrefs_map is None:
+self.gcrefs_map = r_dict(rd_eq, rd_hash)
 try:
 return self.gcrefs_map[gcref]
 except KeyError:
@@ -974,6 +976,8 @@
 # LABELs.  We'd like something better, like "don't spill it",
 # but that's the wrong level...
 index = self._gcref_index(c.value)
+if self.gcrefs_recently_loaded is None:
+self.gcrefs_recently_loaded = {}
 try:
 load_op = self.gcrefs_recently_loaded[index]
 except KeyError:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: more fixes

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83472:db567242f29f
Date: 2016-04-01 00:01 +0200
http://bitbucket.org/pypy/pypy/changeset/db567242f29f/

Log:more fixes

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
@@ -1,4 +1,6 @@
+from rpython.rlib import rgc
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.jit.backend.llsupport.symbolic import WORD
 
 
@@ -14,7 +16,8 @@
 length = obj.array_length
 addr = obj.array_base_addr
 while i < length:
-gc._trace_callback(callback, arg, addr + i * WORD)
+p = rffi.cast(llmemory.Address, addr + i * WORD)
+gc._trace_callback(callback, arg, p)
 i += 1
 lambda_gcrefs_trace = lambda: gcrefs_trace
 
@@ -22,16 +25,17 @@
 # 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...
+rgc.register_custom_trace_hook(GCREFTRACER, lambda_gcrefs_trace)
+length = len(gcrefs)
 tr = lltype.malloc(GCREFTRACER)
+# --no GC from here--
 tr.array_base_addr = array_base_addr
-tr.array_length = 0# incremented as we populate the array_base_addr
+tr.array_length = length
 i = 0
-length = len(gcrefs)
 while i < length:
 p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD)
-# --no GC from here--
 p[0] = rffi.cast(lltype.Signed, gcrefs[i])
-tr.array_length += 1
-# --no GC until here--
 i += 1
+llop.gc_writebarrier(lltype.Void, tr)
+# --no GC until here--
 return tr
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
@@ -9,6 +9,7 @@
 def _trace_callback(self, callback, arg, addr):
 assert callback == "callback"
 assert arg == "arg"
+assert lltype.typeOf(addr) == llmemory.Address
 self.called.append(addr)
 
 
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
@@ -524,6 +524,12 @@
 r_uint(rawstart + looppos),
 r_uint(rawstart + size_excluding_failure_stuff),
 r_uint(rawstart)))
+debug_print("   gc table: 0x%x" % r_uint(rawstart))
+debug_print("   function: 0x%x" % r_uint(rawstart + functionpos))
+debug_print("   loop: 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))
 debug_stop("jit-backend-addr")
 self.patch_pending_failure_recoveries(rawstart)
 #
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy rposix-for-3: Avoid imperative py.test.skip() whenever possible

2016-03-31 Thread rlamy
Author: Ronan Lamy 
Branch: rposix-for-3
Changeset: r83469:c3eceb0fc5db
Date: 2016-03-31 17:13 +0100
http://bitbucket.org/pypy/pypy/changeset/c3eceb0fc5db/

Log:Avoid imperative py.test.skip() whenever possible

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
 compile(f, (str, float))(str(fname), t1)
 assert t1 == os.stat(str(fname)).st_mtime
 
+@win_only
 def test__getfullpathname(self):
-if os.name != 'nt':
-py.test.skip('nt specific function')
 posix = __import__(os.name)
 sysdrv = os.getenv('SystemDrive', 'C:')
 stuff = sysdrv + 'stuff'
@@ -134,10 +131,8 @@
 os.unlink(filename)
 
 
+@py.test.mark.skipif("os.name != 'posix'")
 def test_execve(self):
-if os.name != 'posix':
-py.test.skip('posix specific function')
-
 EXECVE_ENV = {"foo": "bar", "baz": "quux"}
 
 def run_execve(program, args=None, env=None, do_path_lookup=False):
@@ -276,11 +271,8 @@
 assert rposix.isatty(-1) is False
 
 
+@py.test.mark.skipif("not hasattr(os, 'ttyname')")
 class TestOsExpect(ExpectTest):
-def setup_class(cls):
-if not hasattr(os, 'ttyname'):
-py.test.skip("no ttyname")
-
 def test_ttyname(self):
 def f():
 import os
@@ -444,9 +436,8 @@
 except Exception:
 pass
 
+@win_only
 def test_is_valid_fd(self):
-if os.name != 'nt':
-py.test.skip('relevant for windows only')
 assert rposix.is_valid_fd(0) == 1
 fid = open(str(udir.join('validate_test.txt')), 'w')
 fd = fid.fileno()
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy rposix-for-3: Add rposix.fdlistdir(): variant of rposix.listdir() using fdopendir()

2016-03-31 Thread rlamy
Author: Ronan Lamy 
Branch: rposix-for-3
Changeset: r83471:42e156eb8e2c
Date: 2016-03-31 18:12 +0100
http://bitbucket.org/pypy/pypy/changeset/42e156eb8e2c/

Log:Add rposix.fdlistdir(): variant of rposix.listdir() using
fdopendir()

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)
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
@@ -528,6 +528,14 @@
 os.open(u'/tmp/t', 0, 0)
 compile(f, ())
 
+
+def test_fdlistdir(tmpdir):
+tmpdir.join('file').write('text')
+dirfd = os.open(str(tmpdir), os.O_RDONLY)
+result = rposix.fdlistdir(dirfd)
+# Note: fdlistdir() always closes dirfd
+assert result == ['file']
+
 def test_symlinkat(tmpdir):
 tmpdir.join('file').write('text')
 dirfd = os.open(str(tmpdir), os.O_RDONLY)
@@ -537,7 +545,6 @@
 finally:
 os.close(dirfd)
 
-
 def test_renameat(tmpdir):
 tmpdir.join('file').write('text')
 dirfd = os.open(str(tmpdir), os.O_RDONLY)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy rposix-for-3: Implement rposix.fexecve()

2016-03-31 Thread rlamy
Author: Ronan Lamy 
Branch: rposix-for-3
Changeset: r83470:e4260eb4e93c
Date: 2016-03-31 17:20 +0100
http://bitbucket.org/pypy/pypy/changeset/e4260eb4e93c/

Log:Implement rposix.fexecve()

diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1801,6 +1801,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)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: interp_pdb has been renamed

2016-03-31 Thread cfbolz
Author: Carl Friedrich Bolz 
Branch: 
Changeset: r83468:eb3838995550
Date: 2016-03-31 17:20 +0200
http://bitbucket.org/pypy/pypy/changeset/eb3838995550/

Log:interp_pdb has been renamed

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.
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: fixes fixes

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83467:a6f415a30786
Date: 2016-03-31 15:56 +0100
http://bitbucket.org/pypy/pypy/changeset/a6f415a30786/

Log:fixes fixes

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
@@ -155,7 +155,8 @@
 def get_gcref_from_faildescr(self, descr):
 """This assumes that it is called in order for all faildescrs."""
 search = cast_instance_to_gcref(descr)
-while self._allgcrefs[self._allgcrefs_faildescr_next] != search:
+while not _safe_eq(
+self._allgcrefs[self._allgcrefs_faildescr_next], search):
 self._allgcrefs_faildescr_next += 1
 assert self._allgcrefs_faildescr_next < len(self._allgcrefs)
 return self._allgcrefs_faildescr_next
@@ -466,3 +467,8 @@
 r_uint(rawstart + codeendpos)))
 debug_stop("jit-backend-addr")
 
+def _safe_eq(x, y):
+try:
+return x == y
+except AttributeError:# minor mess
+return False
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -1,11 +1,12 @@
 from rpython.rlib import rgc
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, r_dict
 from rpython.rlib.rarithmetic import ovfcheck, highest_bit
 from rpython.rtyper.lltypesystem import llmemory, lltype, rstr
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.jit.metainterp import history
 from rpython.jit.metainterp.history import ConstInt, ConstPtr
 from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers
+from rpython.jit.metainterp.typesystem import rd_eq, rd_hash
 from rpython.jit.codewriter import heaptracker
 from rpython.jit.backend.llsupport.symbolic import (WORD,
 get_array_token)
@@ -96,10 +97,11 @@
 orig_op = op
 replaced = False
 opnum = op.getopnum()
+keep = (opnum == rop.JIT_DEBUG)
 for i in range(op.numargs()):
 orig_arg = op.getarg(i)
 arg = self.get_box_replacement(orig_arg)
-if isinstance(arg, ConstPtr) and bool(arg.value):
+if isinstance(arg, ConstPtr) and bool(arg.value) and not keep:
 arg = self.remove_constptr(arg)
 if orig_arg is not arg:
 if not replaced:
@@ -319,7 +321,7 @@
 # this case means between CALLs or unknown-size mallocs.
 #
 self.gcrefs_output_list = gcrefs_output_list
-self.gcrefs_map = {}
+self.gcrefs_map = r_dict(rd_eq, rd_hash)   # rdict {gcref: index}
 self.gcrefs_recently_loaded = {}
 operations = self.remove_bridge_exception(operations)
 self._changed_op = None
@@ -956,20 +958,12 @@
 self.gcrefs_recently_loaded.clear()
 
 def _gcref_index(self, gcref):
-if we_are_translated():
-# can only use the dictionary after translation
-try:
-return self.gcrefs_map[gcref]
-except KeyError:
-pass
-index = len(self.gcrefs_output_list)
-self.gcrefs_map[gcref] = index
-else:
-# untranslated: linear scan
-for i, gcref1 in enumerate(self.gcrefs_output_list):
-if gcref == gcref1:
-return i
-index = len(self.gcrefs_output_list)
+try:
+return self.gcrefs_map[gcref]
+except KeyError:
+pass
+index = len(self.gcrefs_output_list)
+self.gcrefs_map[gcref] = index
 self.gcrefs_output_list.append(gcref)
 return index
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: fix the test

2016-03-31 Thread fijal
Author: fijal
Branch: 
Changeset: r83465:643df004248e
Date: 2016-03-31 16:49 +0200
http://bitbucket.org/pypy/pypy/changeset/643df004248e/

Log:fix the test

diff --git a/rpython/jit/metainterp/test/test_virtualref.py 
b/rpython/jit/metainterp/test/test_virtualref.py
--- a/rpython/jit/metainterp/test/test_virtualref.py
+++ b/rpython/jit/metainterp/test/test_virtualref.py
@@ -578,7 +578,6 @@
 n -= 1
 return res
 #
-py.test.raises(InvalidVirtualRef, "fn(10)")
 py.test.raises(UnknownException, "self.meta_interp(fn, [10])")
 
 def test_call_virtualref_already_forced(self):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: merge

2016-03-31 Thread fijal
Author: fijal
Branch: 
Changeset: r83466:786c1c380bd8
Date: 2016-03-31 16:49 +0200
http://bitbucket.org/pypy/pypy/changeset/786c1c380bd8/

Log:merge

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -277,19 +277,12 @@
 raise NotImplementedError
 
 def get_traceback(self):
-"""Calling this marks the PyTraceback as escaped, i.e. it becomes
-accessible and inspectable by app-level Python code.
+"""Get the PyTraceback object, for app-level Python code.
 """
 return self._application_traceback
 
 def set_traceback(self, traceback):
-"""Set the current traceback.  It should either be a traceback
-pointing to some already-escaped frame, or a traceback for the
-current frame.  To support the latter case we do not mark the
-frame as escaped.  The idea is that it will be marked as escaping
-only if the exception really propagates out of this frame, by
-executioncontext.leave() being called with got_exception=True.
-"""
+"""Set the current traceback."""
 self._application_traceback = traceback
 
 
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
@@ -645,15 +645,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)
+else:
+mc.MOV_ri(X86_64_SCRATCH_REG.value, adr_new_target)
+

[pypy-commit] pypy jit-constptr-2: progress for x86-64

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83464:27b8d73fef68
Date: 2016-03-31 15:27 +0100
http://bitbucket.org/pypy/pypy/changeset/27b8d73fef68/

Log:progress for x86-64

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
@@ -23,10 +23,11 @@
 
 class GuardToken(object):
 def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
- guard_opnum, frame_depth):
+ guard_opnum, frame_depth, faildescrindex):
 assert isinstance(faildescr, AbstractFailDescr)
 self.cpu = cpu
 self.faildescr = faildescr
+self.faildescrindex = faildescrindex
 self.failargs = failargs
 self.fail_locs = fail_locs
 self.gcmap = self.compute_gcmap(gcmap, failargs,
@@ -144,6 +145,21 @@
 self.codemap_builder = CodemapBuilder()
 self._finish_gcmap = lltype.nullptr(jitframe.GCMAP)
 
+def setup_gcrefs_list(self, allgcrefs):
+self._allgcrefs = allgcrefs
+self._allgcrefs_faildescr_next = 0
+
+def teardown_gcrefs_list(self):
+self._allgcrefs = None
+
+def get_gcref_from_faildescr(self, descr):
+"""This assumes that it is called in order for all faildescrs."""
+search = cast_instance_to_gcref(descr)
+while self._allgcrefs[self._allgcrefs_faildescr_next] != search:
+self._allgcrefs_faildescr_next += 1
+assert self._allgcrefs_faildescr_next < len(self._allgcrefs)
+return self._allgcrefs_faildescr_next
+
 def set_debug(self, v):
 r = self._debug
 self._debug = v
@@ -186,8 +202,7 @@
 break
 exc = guardtok.must_save_exception()
 target = self.failure_recovery_code[exc + 2 * withfloats]
-fail_descr = cast_instance_to_gcref(guardtok.faildescr)
-fail_descr = rffi.cast(lltype.Signed, fail_descr)
+faildescrindex = guardtok.faildescrindex
 base_ofs = self.cpu.get_baseofs_of_frame_field()
 #
 # in practice, about 2/3rd of 'positions' lists that we build are
@@ -229,7 +244,7 @@
 self._previous_rd_locs = positions
 # write down the positions of locs
 guardtok.faildescr.rd_locs = positions
-return fail_descr, target
+return faildescrindex, target
 
 def enter_portal_frame(self, op):
 if self.cpu.HAS_CODEMAP:
@@ -288,7 +303,7 @@
 
 gcref = cast_instance_to_gcref(value)
 if gcref:
-rgc._make_sure_does_not_move(gcref)
+rgc._make_sure_does_not_move(gcref)# but should be prebuilt
 value = rffi.cast(lltype.Signed, gcref)
 je_location = self._call_assembler_check_descr(value, tmploc)
 #
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
@@ -514,7 +514,7 @@
 full_size = self.mc.get_relative_pos()
 #
 rawstart = self.materialize_loop(looptoken)
-self.patch_gcref_table(looptoken, allgcrefs, rawstart)
+self.patch_gcref_table(looptoken, rawstart)
 self.patch_stack_checks(frame_depth_no_fixed_size + 
JITFRAME_FIXED_SIZE,
 rawstart)
 looptoken._ll_loop_code = looppos + rawstart
@@ -582,7 +582,7 @@
 fullsize = self.mc.get_relative_pos()
 #
 rawstart = self.materialize_loop(original_loop_token)
-self.patch_gcref_table(original_loop_token, allgcrefs, rawstart)
+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)
@@ -669,12 +669,14 @@
 assert mc.get_relative_pos() == 0
 for i in range(gcref_table_size):
 mc.writechar('\x00')
+self.setup_gcrefs_list(allgcrefs)
 
-def patch_gcref_table(self, looptoken, allgcrefs, rawstart):
+def patch_gcref_table(self, looptoken, rawstart):
 assert IS_X86_64, "XXX"
-tracer = gcreftracer.make_gcref_tracer(rawstart, allgcrefs)
+tracer = gcreftracer.make_gcref_tracer(rawstart, self._allgcrefs)
 gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken)
 gcreftracers.append(tracer)# keepalive
+self.teardown_gcrefs_list()
 
 def write_pending_failure_recoveries(self, regalloc):
 # for each pending guard, generate the code of the recovery stub
@@ -1386,16 +1388,20 @@
 genop_cast_ptr_to_int = _genop_same_as
 genop_cast_int_to_ptr = _genop_same_as
 
+def _patch_load_from_gc_table(self, index):
+# must be called immediately after a "p"-mode instruction
+# has been emitted
+

[pypy-commit] pypy default: _patch_jump_for_descr cannot be used to patch any jump (stitch bridge would not work if the offset was too big. thx arigato)

2016-03-31 Thread plan_rich
Author: Richard Plangger 
Branch: 
Changeset: r83463:c5ec7f300d0a
Date: 2016-03-31 15:58 +0200
http://bitbucket.org/pypy/pypy/changeset/c5ec7f300d0a/

Log:_patch_jump_for_descr cannot be used to patch any jump (stitch
bridge would not work if the offset was too big. thx arigato)

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
@@ -645,15 +645,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)
+else:
+mc.MOV_ri(X86_64_SCRATCH_REG.value, adr_new_target)
+mc.JMP_r(X86_64_SCRATCH_REG.value)
+mc.copy_to_raw_memory(adr_jump_offset)
+
 def write_pending_failure_recoveries(self, regalloc):
 # for each pending guard, generate the code of the recovery stub
 # at the end of self.mc.
@@ -791,10 +804,6 @@
 
 def patch_jump_for_descr(self, faildescr, adr_new_target):
 adr_jump_offset = faildescr.adr_jump_offset
-self._patch_jump_for_descr(adr_jump_offset, adr_new_target)
-faildescr.adr_jump_offset = 0# means "patched"
-
-def _patch_jump_for_descr(self, adr_jump_offset, adr_new_target):
 assert adr_jump_offset != 0
 offset = adr_new_target - (adr_jump_offset + 4)
 # If the new target fits within a rel32 of the jump, just patch
@@ -815,6 +824,7 @@
 p = rffi.cast(rffi.INTP, adr_jump_offset)
 adr_target = adr_jump_offset + 4 + rffi.cast(lltype.Signed, p[0])
 mc.copy_to_raw_memory(adr_target)
+faildescr.adr_jump_offset = 0# means "patched"
 
 def fixup_target_tokens(self, rawstart):
 for targettoken in self.target_tokens_currently_compiling:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: Implementation and test of the %rip+offset addressing mode on x86-64

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83461:ecde1ca1079a
Date: 2016-03-31 14:44 +0100
http://bitbucket.org/pypy/pypy/changeset/ecde1ca1079a/

Log:Implementation and test of the %rip+offset addressing mode on x86-64

diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py
--- a/rpython/jit/backend/x86/rx86.py
+++ b/rpython/jit/backend/x86/rx86.py
@@ -297,6 +297,20 @@
 return encode_abs, argnum, None, None
 
 # 
+# ***X86_64 only*** 
+# Emit a mod/rm referencing an address "RIP + immediate_offset".
+
+@specialize.arg(2)
+def encode_rip_offset(mc, immediate, _, orbyte):
+assert mc.WORD == 8
+mc.writechar(chr(0x05 | orbyte))
+mc.writeimm32(immediate)
+return 0
+
+def rip_offset(argnum):
+return encode_rip_offset, argnum, None, None
+
+# 
 # For 64-bits mode: the REX.W, REX.R, REX.X, REG.B prefixes
 
 REX_W = 8
@@ -914,6 +928,7 @@
 add_insn('m', mem_reg_plus_const(modrm_argnum))
 add_insn('a', mem_reg_plus_scaled_reg_plus_const(modrm_argnum))
 add_insn('j', abs_(modrm_argnum))
+add_insn('p', rip_offset(modrm_argnum))
 
 # Define a regular MOV, and a variant MOV32 that only uses the low 4 bytes of a
 # register
diff --git a/rpython/jit/backend/x86/test/test_rx86_32_auto_encoding.py 
b/rpython/jit/backend/x86/test/test_rx86_32_auto_encoding.py
--- a/rpython/jit/backend/x86/test/test_rx86_32_auto_encoding.py
+++ b/rpython/jit/backend/x86/test/test_rx86_32_auto_encoding.py
@@ -279,6 +279,8 @@
 if modes:
 tests = self.get_all_tests()
 m = modes[0]
+if m == 'p' and self.WORD == 4:
+return []
 lst = tests[m]()
 random.shuffle(lst)
 if methname == 'PSRAD_xi' and m == 'i':
diff --git a/rpython/jit/backend/x86/test/test_rx86_64_auto_encoding.py 
b/rpython/jit/backend/x86/test/test_rx86_64_auto_encoding.py
--- a/rpython/jit/backend/x86/test/test_rx86_64_auto_encoding.py
+++ b/rpython/jit/backend/x86/test/test_rx86_64_auto_encoding.py
@@ -51,3 +51,19 @@
 def test_extra_MOV_ri64(self):
 self.imm32_tests = self.imm64_tests  # patch on 'self'
 self.complete_test('MOV_ri')
+
+def rip_relative_tests(self):
+return [-0x8000, 0x7FFF, 128, 256, -129, -255, 0, 127]
+
+def get_all_tests(self):
+d = super(TestRx86_64, self).get_all_tests()
+d['p'] = self.rip_relative_tests
+return d
+
+def assembler_operand_rip_relative(self, value):
+return '%d(%%rip)' % value
+
+def get_all_assembler_operands(self):
+d = super(TestRx86_64, self).get_all_assembler_operands()
+d['p'] = self.assembler_operand_rip_relative
+return d
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: add a __pypy__._promote

2016-03-31 Thread cfbolz
Author: Carl Friedrich Bolz 
Branch: 
Changeset: r83460:422ee5506a5a
Date: 2016-03-31 15:21 +0200
http://bitbucket.org/pypy/pypy/changeset/422ee5506a5a/

Log:add a __pypy__._promote

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
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy new-jit-log: catchup with default

2016-03-31 Thread plan_rich
Author: Richard Plangger 
Branch: new-jit-log
Changeset: r83459:83bff96fb266
Date: 2016-03-31 14:43 +0200
http://bitbucket.org/pypy/pypy/changeset/83bff96fb266/

Log:catchup with default

diff too long, truncating to 2000 out of 9743 lines

diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -67,7 +67,8 @@
 subvalue = subfield.ctype
 fields[subname] = Field(subname,
 relpos, 
subvalue._sizeofinstances(),
-subvalue, i, is_bitfield)
+subvalue, i, is_bitfield,
+inside_anon_field=fields[name])
 else:
 resnames.append(name)
 names = resnames
@@ -77,13 +78,15 @@
 
 
 class Field(object):
-def __init__(self, name, offset, size, ctype, num, is_bitfield):
+def __init__(self, name, offset, size, ctype, num, is_bitfield,
+ inside_anon_field=None):
 self.__dict__['name'] = name
 self.__dict__['offset'] = offset
 self.__dict__['size'] = size
 self.__dict__['ctype'] = ctype
 self.__dict__['num'] = num
 self.__dict__['is_bitfield'] = is_bitfield
+self.__dict__['inside_anon_field'] = inside_anon_field
 
 def __setattr__(self, name, value):
 raise AttributeError(name)
@@ -95,6 +98,8 @@
 def __get__(self, obj, cls=None):
 if obj is None:
 return self
+if self.inside_anon_field is not None:
+return getattr(self.inside_anon_field.__get__(obj), self.name)
 if self.is_bitfield:
 # bitfield member, use direct access
 return obj._buffer.__getattr__(self.name)
@@ -105,6 +110,9 @@
 return fieldtype._CData_output(suba, obj, offset)
 
 def __set__(self, obj, value):
+if self.inside_anon_field is not None:
+setattr(self.inside_anon_field.__get__(obj), self.name, value)
+return
 fieldtype = self.ctype
 cobj = fieldtype.from_param(value)
 key = keepalive_key(self.num)
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -46,7 +46,6 @@
 except detect_cpu.ProcessorAutodetectError:
 pass
 
-
 translation_modules = default_modules.copy()
 translation_modules.update([
 "fcntl", "time", "select", "signal", "_rawffi", "zlib", "struct", "_md5",
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -23,3 +23,15 @@
 
 Implement yet another strange numpy indexing compatibility; indexing by a 
scalar 
 returns a scalar
+
+.. branch: fix_transpose_for_list_v3
+
+Allow arguments to transpose to be sequences
+
+.. branch: jit-leaner-frontend
+
+Improve the tracing speed in the frontend as well as heapcache by using a more 
compact representation
+of traces
+
+.. branch: win32-lib-name
+
diff --git a/pypy/goal/targetpypystandalone.py 
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -240,8 +240,9 @@
 "when --shared is on (it is by default). "
 "See issue #1971.")
 if sys.platform == 'win32':
-config.translation.libname = '..\\..\\libs\\python27.lib'
-thisdir.join('..', '..', 'libs').ensure(dir=1)
+libdir = thisdir.join('..', '..', 'libs')
+libdir.ensure(dir=1)
+config.translation.libname = str(libdir.join('python27.lib'))
 
 if config.translation.thread:
 config.objspace.usemodules.thread = True
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -277,27 +277,12 @@
 raise NotImplementedError
 
 def get_traceback(self):
-"""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.
+"""Get the PyTraceback object, for app-level Python code.
 """
-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
+return self._application_traceback
 
 def set_traceback(self, traceback):
-"""Set the current traceback.  It should either be a traceback
-

[pypy-commit] pypy jit-constptr-2: (fijal, arigo)

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83456:7262e1468002
Date: 2016-03-31 13:36 +0100
http://bitbucket.org/pypy/pypy/changeset/7262e1468002/

Log:(fijal, arigo)

Creating and freeing gcreftracers

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
@@ -17,3 +17,21 @@
 gc._trace_callback(callback, arg, addr + i * WORD)
 i += 1
 lambda_gcrefs_trace = lambda: gcrefs_trace
+
+def make_gcref_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...
+tr = lltype.malloc(GCREFTRACER)
+tr.array_base_addr = array_base_addr
+tr.array_length = 0# incremented as we populate the array_base_addr
+i = 0
+length = len(gcrefs)
+while i < length:
+p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD)
+# --no GC from here--
+p[0] = rffi.cast(lltype.Signed, gcrefs[i])
+tr.array_length += 1
+# --no GC until here--
+i += 1
+return tr
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
@@ -246,6 +246,13 @@
 
 def free_loop_and_bridges(self, compiled_loop_token):
 AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
+# turn off all gcreftracers
+tracers = compiled_loop_token.asmmemmgr_gcreftracers
+if tracers is not None:
+compiled_loop_token.asmmemmgr_gcreftracers = None
+for tracer in tracers:
+tracer.array_length = 0
+# then free all blocks of code and raw data
 blocks = compiled_loop_token.asmmemmgr_blocks
 if blocks is not None:
 compiled_loop_token.asmmemmgr_blocks = 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,5 +1,6 @@
 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
 
 
 class FakeGC:
@@ -26,3 +27,14 @@
 for i in range(3):
 assert gc.called[i] == rffi.cast(llmemory.Address, base + i * WORD)
 lltype.free(a, flavor='raw')
+
+def test_make_gcref_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])
+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')
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -285,7 +285,7 @@
 
 class CompiledLoopToken(object):
 asmmemmgr_blocks = None
-asmmemmgr_gcroots = 0
+asmmemmgr_gcreftracers = None
 
 def __init__(self, cpu, number):
 cpu.tracker.total_compiled_loops += 1
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy new-jit-log: minor changed in the emitted format

2016-03-31 Thread plan_rich
Author: Richard Plangger 
Branch: new-jit-log
Changeset: r83457:26c9229ea302
Date: 2016-03-31 14:30 +0200
http://bitbucket.org/pypy/pypy/changeset/26c9229ea302/

Log:minor changed in the emitted format

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
@@ -583,7 +583,7 @@
 self.patch_pending_failure_recoveries(rawstart)
 # patch the jump from original guard
 if logger:
-logger.log_patch_guard(faildescr.adr_jump_offset, rawstart)
+logger.log_patch_guard(descr_number, rawstart)
 self.patch_jump_for_descr(faildescr, rawstart)
 ops_offset = self.mc.ops_offset
 frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
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
@@ -23,7 +23,7 @@
 MARK_TRACE_ASM = 0x18
 
 # the machine code was patched (e.g. guard)
-MARK_ASM_PATCH = 0x19
+MARK_STITCH_BRIDGE = 0x19
 
 IS_32_BIT = sys.maxint == 2**31-1
 
@@ -61,14 +61,13 @@
 memo = {}
 return LogTrace(tag, memo, metainterp_sd, mc, self)
 
-def log_patch_guard(self, addr, target_addr):
-if self.cintf.jitlog_filter(MARK_ASM_PATCH):
+def log_patch_guard(self, descr_number, addr):
+if self.cintf.jitlog_filter(MARK_STITCH_BRIDGE):
 return
-le_addr_write = self.encode_le_addr(addr)
-le_len = self.encode_le_32bit(8)
-le_addr = self.encode_le_addr(target_addr)
-lst = [le_addr, le_len, le_addr]
-self.cintf.jitlog_filter(MARK_ASM_PATCH, ''.join(lst))
+le_descr_number = self.encode_le_addr(descr_number)
+le_addr = self.encode_le_addr(addr)
+lst = [le_descr_number, le_addr]
+self.write_marked(MARK_STITCH_BRIDGE, ''.join(lst))
 
 def encode_str(self, string):
 return self.encode_le_32bit(len(string)) + string
@@ -163,7 +162,9 @@
 descr_str = descr.repr_of_descr()
 line = line + ',' + descr_str
 string = self.logger.encode_str(line)
-return MARK_RESOP_DESCR, le_opnum + string
+descr_number = compute_unique_id(descr)
+le_descr_number = self.logger.encode_le_addr(descr_number)
+return MARK_RESOP_DESCR, le_opnum + string + le_descr_number
 else:
 string = self.logger.encode_str(line)
 return MARK_RESOP, le_opnum + string
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: is_jit_debug method was moved. fixes crashes on s390x

2016-03-31 Thread plan_rich
Author: Richard Plangger 
Branch: 
Changeset: r83458:f1a599da9f67
Date: 2016-03-31 14:37 +0200
http://bitbucket.org/pypy/pypy/changeset/f1a599da9f67/

Log:is_jit_debug method was moved. fixes crashes on s390x

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 op.is_jit_debug():
+if rop.is_jit_debug(op):
 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 jit-constptr-2: (fijal, arigo)

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83455:17289fc949d4
Date: 2016-03-31 13:20 +0100
http://bitbucket.org/pypy/pypy/changeset/17289fc949d4/

Log:(fijal, arigo)

Start on this object

diff --git a/rpython/jit/backend/llsupport/gcreftracer.py 
b/rpython/jit/backend/llsupport/gcreftracer.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/gcreftracer.py
@@ -0,0 +1,19 @@
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.jit.backend.llsupport.symbolic import WORD
+
+
+GCREFTRACER = lltype.GcStruct(
+'GCREFTRACER',
+('array_base_addr', lltype.Signed),
+('array_length', lltype.Signed),
+rtti=True)
+
+def gcrefs_trace(gc, obj_addr, callback, arg):
+obj = llmemory.cast_adr_to_ptr(obj_addr, lltype.Ptr(GCREFTRACER))
+i = 0
+length = obj.array_length
+addr = obj.array_base_addr
+while i < length:
+gc._trace_callback(callback, arg, addr + i * WORD)
+i += 1
+lambda_gcrefs_trace = lambda: gcrefs_trace
diff --git a/rpython/jit/backend/llsupport/test/test_gcreftracer.py 
b/rpython/jit/backend/llsupport/test/test_gcreftracer.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/test/test_gcreftracer.py
@@ -0,0 +1,28 @@
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.jit.backend.llsupport.gcreftracer import GCREFTRACER, gcrefs_trace
+
+
+class FakeGC:
+def __init__(self):
+self.called = []
+def _trace_callback(self, callback, arg, addr):
+assert callback == "callback"
+assert arg == "arg"
+self.called.append(addr)
+
+
+def test_gcreftracer():
+a = lltype.malloc(rffi.CArray(lltype.Signed), 3, flavor='raw')
+a[0] = 123
+a[1] = 456
+a[2] = 789
+tr = lltype.malloc(GCREFTRACER)
+tr.array_base_addr = base = rffi.cast(lltype.Signed, a)
+tr.array_length = 3
+gc = FakeGC()
+gcrefs_trace(gc, llmemory.cast_ptr_to_adr(tr), "callback", "arg")
+assert len(gc.called) == 3
+WORD = rffi.sizeof(lltype.Signed)
+for i in range(3):
+assert gc.called[i] == rffi.cast(llmemory.Address, base + i * WORD)
+lltype.free(a, flavor='raw')
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: more tests, and store the descr of guards and finish operations

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83454:e7787f9361a4
Date: 2016-03-31 11:47 +0100
http://bitbucket.org/pypy/pypy/changeset/e7787f9361a4/

Log:more tests, and store the descr of guards and finish operations

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -2,6 +2,7 @@
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.rarithmetic import ovfcheck, highest_bit
 from rpython.rtyper.lltypesystem import llmemory, lltype, rstr
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.jit.metainterp import history
 from rpython.jit.metainterp.history import ConstInt, ConstPtr
 from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers
@@ -94,6 +95,7 @@
 op = self.get_box_replacement(op)
 orig_op = op
 replaced = False
+opnum = op.getopnum()
 for i in range(op.numargs()):
 orig_arg = op.getarg(i)
 arg = self.get_box_replacement(orig_arg)
@@ -101,16 +103,19 @@
 arg = self.remove_constptr(arg)
 if orig_arg is not arg:
 if not replaced:
-op = op.copy_and_change(op.getopnum())
+op = op.copy_and_change(opnum)
 orig_op.set_forwarded(op)
 replaced = True
 op.setarg(i, arg)
-if rop.is_guard(op.opnum):
+if rop.is_guard(opnum):
 if not replaced:
-op = op.copy_and_change(op.getopnum())
+op = op.copy_and_change(opnum)
 orig_op.set_forwarded(op)
 op.setfailargs([self.get_box_replacement(a, True)
 for a in op.getfailargs()])
+if rop.is_guard(opnum) or opnum == rop.FINISH:
+llref = cast_instance_to_gcref(op.getdescr())
+self.gcrefs_output_list.append(llref)
 self._newops.append(op)
 
 def replace_op_with(self, op, newop):
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -79,6 +79,7 @@
 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
 myT = lltype.cast_opaque_ptr(llmemory.GCREF,
  lltype.malloc(T, zero=True))
+self.myT = myT
 #
 A = lltype.GcArray(lltype.Signed)
 adescr = get_array_descr(self.gc_ll_descr, A)
@@ -116,6 +117,10 @@
 zdescr = get_field_descr(self.gc_ll_descr, R1, 'z')
 myR1 = lltype.cast_opaque_ptr(llmemory.GCREF,
   lltype.malloc(R1, zero=True))
+myR1b = lltype.cast_opaque_ptr(llmemory.GCREF,
+   lltype.malloc(R1, zero=True))
+self.myR1 = myR1
+self.myR1b = myR1b
 #
 E = lltype.GcStruct('Empty')
 edescr = get_size_descr(self.gc_ll_descr, E)
@@ -178,9 +183,10 @@
 ops = parse(frm_operations, namespace=namespace)
 expected = parse(to_operations % Evaluator(namespace),
  namespace=namespace)
+self.gcrefs = []
 operations = self.gc_ll_descr.rewrite_assembler(self.cpu,
 ops.operations,
-[])
+self.gcrefs)
 remap = {}
 for a, b in zip(ops.inputargs, expected.inputargs):
 remap[b] = a
@@ -1297,6 +1303,7 @@
 gc_store(p0, %(xdescr.offset)s, i1, %(xdescr.field_size)s)
 jump()
 """)
+assert self.gcrefs == [self.myR1]
 
 def test_load_from_gc_table_1p(self):
 self.check_rewrite("""
@@ -1310,6 +1317,7 @@
 gc_store(p0, %(tzdescr.offset)s, i1, %(tzdescr.field_size)s)
 jump()
 """)
+assert self.gcrefs == [self.myT]
 
 def test_load_from_gc_table_2(self):
 self.check_rewrite("""
@@ -1324,6 +1332,7 @@
 gc_store(p0, %(ydescr.offset)s, f2, %(ydescr.field_size)s)
 jump()
 """)
+assert self.gcrefs == [self.myR1]
 
 def test_load_from_gc_table_3(self):
 self.check_rewrite("""
@@ -1341,3 +1350,34 @@
 gc_store(p1, %(ydescr.offset)s, f2, %(ydescr.field_size)s)
 jump()
 """)
+assert self.gcrefs == [self.myR1]
+
+def test_load_from_gc_table_4(self):
+self.check_rewrite("""
+[i1, f2]
+setfield_gc(ConstPtr(myR1), i1, descr=xdescr)
+setfield_gc(ConstPtr(myR1b), f2, descr=ydescr)
+jump()
+""", """
+[i1, f2]
+p0 = 

[pypy-commit] pypy jit-constptr-2: Cache LOAD_FROM_GC_TABLE, passing tests added in cc9cdb30a812

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83453:85ae1950770a
Date: 2016-03-31 11:21 +0100
http://bitbucket.org/pypy/pypy/changeset/85ae1950770a/

Log:Cache LOAD_FROM_GC_TABLE, passing tests added in cc9cdb30a812

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -315,6 +315,7 @@
 #
 self.gcrefs_output_list = gcrefs_output_list
 self.gcrefs_map = {}
+self.gcrefs_recently_loaded = {}
 operations = self.remove_bridge_exception(operations)
 self._changed_op = None
 for i in range(len(operations)):
@@ -337,8 +338,7 @@
 elif rop.can_malloc(op.opnum):
 self.emitting_an_operation_that_can_collect()
 elif op.getopnum() == rop.LABEL:
-self.emitting_an_operation_that_can_collect()
-self._known_lengths.clear()
+self.emit_label()
 # -- write barriers --
 if self.gc_ll_descr.write_barrier_descr is not None:
 if op.getopnum() == rop.SETFIELD_GC:
@@ -945,6 +945,11 @@
 return operations[:start] + operations[start+3:]
 return operations
 
+def emit_label(self):
+self.emitting_an_operation_that_can_collect()
+self._known_lengths.clear()
+self.gcrefs_recently_loaded.clear()
+
 def _gcref_index(self, gcref):
 if we_are_translated():
 # can only use the dictionary after translation
@@ -966,7 +971,14 @@
 def remove_constptr(self, c):
 """Remove all ConstPtrs, and replace them with load_from_gc_table.
 """
+# Note: currently, gcrefs_recently_loaded is only cleared in
+# LABELs.  We'd like something better, like "don't spill it",
+# but that's the wrong level...
 index = self._gcref_index(c.value)
-load_op = ResOperation(rop.LOAD_FROM_GC_TABLE, [ConstInt(index)])
-self._newops.append(load_op)
+try:
+load_op = self.gcrefs_recently_loaded[index]
+except KeyError:
+load_op = ResOperation(rop.LOAD_FROM_GC_TABLE, [ConstInt(index)])
+self._newops.append(load_op)
+self.gcrefs_recently_loaded[index] = load_op
 return load_op
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: A branch in which to play again with removing the minor collection needed to make ConstPtrs non-movable

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83451:f350a149824b
Date: 2016-03-31 09:48 +0100
http://bitbucket.org/pypy/pypy/changeset/f350a149824b/

Log:A branch in which to play again with removing the minor collection
needed to make ConstPtrs non-movable

___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy jit-constptr-2: (arigo, fijal around)

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: jit-constptr-2
Changeset: r83452:cc9cdb30a812
Date: 2016-03-31 11:07 +0100
http://bitbucket.org/pypy/pypy/changeset/cc9cdb30a812/

Log:(arigo, fijal around)

Add a LOAD_FROM_GC_TABLE operation, emitted by rewrite.py. It should
be a replacement for gc.py's _record_constptr.

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
@@ -137,7 +137,7 @@
 v = op.getarg(i)
 if isinstance(v, ConstPtr) and bool(v.value):
 p = v.value
-if rgc._make_sure_does_not_move(p):
+if not rgc.can_move(p):
 gcrefs_output_list.append(p)
 else:
 if l is None:
@@ -177,7 +177,10 @@
 
 def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
 rewriter = GcRewriterAssembler(self, cpu)
-newops = rewriter.rewrite(operations)
+newops = rewriter.rewrite(operations, gcrefs_output_list)
+return newops
+
+XXX # kill the rest
 
 # the key is an operation that contains a ConstPtr as an argument and
 # this ConstPtrs pointer might change as it points to an object that
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -97,6 +97,8 @@
 for i in range(op.numargs()):
 orig_arg = op.getarg(i)
 arg = self.get_box_replacement(orig_arg)
+if isinstance(arg, ConstPtr) and bool(arg.value):
+arg = self.remove_constptr(arg)
 if orig_arg is not arg:
 if not replaced:
 op = op.copy_and_change(op.getopnum())
@@ -304,13 +306,15 @@
 return False
 
 
-def rewrite(self, operations):
+def rewrite(self, operations, gcrefs_output_list):
 # we can only remember one malloc since the next malloc can possibly
 # collect; but we can try to collapse several known-size mallocs into
 # one, both for performance and to reduce the number of write
 # barriers.  We do this on each "basic block" of operations, which in
 # this case means between CALLs or unknown-size mallocs.
 #
+self.gcrefs_output_list = gcrefs_output_list
+self.gcrefs_map = {}
 operations = self.remove_bridge_exception(operations)
 self._changed_op = None
 for i in range(len(operations)):
@@ -940,3 +944,29 @@
 operations[start+2].getopnum() == rop.RESTORE_EXCEPTION):
 return operations[:start] + operations[start+3:]
 return operations
+
+def _gcref_index(self, gcref):
+if we_are_translated():
+# can only use the dictionary after translation
+try:
+return self.gcrefs_map[gcref]
+except KeyError:
+pass
+index = len(self.gcrefs_output_list)
+self.gcrefs_map[gcref] = index
+else:
+# untranslated: linear scan
+for i, gcref1 in enumerate(self.gcrefs_output_list):
+if gcref == gcref1:
+return i
+index = len(self.gcrefs_output_list)
+self.gcrefs_output_list.append(gcref)
+return index
+
+def remove_constptr(self, c):
+"""Remove all ConstPtrs, and replace them with load_from_gc_table.
+"""
+index = self._gcref_index(c.value)
+load_op = ResOperation(rop.LOAD_FROM_GC_TABLE, [ConstInt(index)])
+self._newops.append(load_op)
+return load_op
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -10,7 +10,7 @@
 from rpython.jit.metainterp.optimizeopt.util import equaloplists
 from rpython.jit.metainterp.history import JitCellToken, FLOAT
 from rpython.jit.metainterp.history import AbstractFailDescr
-from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.rtyper import rclass
 from rpython.jit.backend.x86.arch import WORD
 from rpython.jit.backend.llsupport.symbolic import (WORD,
@@ -77,6 +77,8 @@
 tdescr = get_size_descr(self.gc_ll_descr, T)
 tdescr.tid = 5678
 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
+myT = lltype.cast_opaque_ptr(llmemory.GCREF,
+ lltype.malloc(T, zero=True))
 #
 A = lltype.GcArray(lltype.Signed)
 adescr = get_array_descr(self.gc_ll_descr, A)
@@ -112,6 +114,8 @@
 xdescr = get_field_descr(self.gc_ll_descr, R1, 'x')
 ydescr = 

[pypy-commit] pypy default: Kill outdated comments

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r83450:2f0cad6d0069
Date: 2016-03-31 10:11 +0200
http://bitbucket.org/pypy/pypy/changeset/2f0cad6d0069/

Log:Kill outdated comments

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -277,19 +277,12 @@
 raise NotImplementedError
 
 def get_traceback(self):
-"""Calling this marks the PyTraceback as escaped, i.e. it becomes
-accessible and inspectable by app-level Python code.
+"""Get the PyTraceback object, for app-level Python code.
 """
 return self._application_traceback
 
 def set_traceback(self, traceback):
-"""Set the current traceback.  It should either be a traceback
-pointing to some already-escaped frame, or a traceback for the
-current frame.  To support the latter case we do not mark the
-frame as escaped.  The idea is that it will be marked as escaping
-only if the exception really propagates out of this frame, by
-executioncontext.leave() being called with got_exception=True.
-"""
+"""Set the current traceback."""
 self._application_traceback = traceback
 
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Issue #2230: _anonymous_ fields were tested at the level of classes, but

2016-03-31 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r83449:3d53b5735ff2
Date: 2016-03-31 10:07 +0200
http://bitbucket.org/pypy/pypy/changeset/3d53b5735ff2/

Log:Issue #2230: _anonymous_ fields were tested at the level of classes,
but didn't work on instances

diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -67,7 +67,8 @@
 subvalue = subfield.ctype
 fields[subname] = Field(subname,
 relpos, 
subvalue._sizeofinstances(),
-subvalue, i, is_bitfield)
+subvalue, i, is_bitfield,
+inside_anon_field=fields[name])
 else:
 resnames.append(name)
 names = resnames
@@ -77,13 +78,15 @@
 
 
 class Field(object):
-def __init__(self, name, offset, size, ctype, num, is_bitfield):
+def __init__(self, name, offset, size, ctype, num, is_bitfield,
+ inside_anon_field=None):
 self.__dict__['name'] = name
 self.__dict__['offset'] = offset
 self.__dict__['size'] = size
 self.__dict__['ctype'] = ctype
 self.__dict__['num'] = num
 self.__dict__['is_bitfield'] = is_bitfield
+self.__dict__['inside_anon_field'] = inside_anon_field
 
 def __setattr__(self, name, value):
 raise AttributeError(name)
@@ -95,6 +98,8 @@
 def __get__(self, obj, cls=None):
 if obj is None:
 return self
+if self.inside_anon_field is not None:
+return getattr(self.inside_anon_field.__get__(obj), self.name)
 if self.is_bitfield:
 # bitfield member, use direct access
 return obj._buffer.__getattr__(self.name)
@@ -105,6 +110,9 @@
 return fieldtype._CData_output(suba, obj, offset)
 
 def __set__(self, obj, value):
+if self.inside_anon_field is not None:
+setattr(self.inside_anon_field.__get__(obj), self.name, value)
+return
 fieldtype = self.ctype
 cobj = fieldtype.from_param(value)
 key = keepalive_key(self.num)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
@@ -57,3 +57,32 @@
 assert Y.y.offset == sizeof(c_int) * 2
 
 assert Y._names_ == ['x', 'a', 'b', 'y']
+
+def test_anonymous_fields_on_instance(self):
+# this is about the *instance-level* access of anonymous fields,
+# which you'd guess is the most common, but used not to work
+# (issue #2230)
+
+class B(Structure):
+_fields_ = [("x", c_int), ("y", c_int), ("z", c_int)]
+class A(Structure):
+_anonymous_ = ["b"]
+_fields_ = [("b", B)]
+
+a = A()
+a.x = 5
+assert a.x == 5
+assert a.b.x == 5
+a.b.x += 1
+assert a.x == 6
+
+class C(Structure):
+_anonymous_ = ["a"]
+_fields_ = [("v", c_int), ("a", A)]
+
+c = C()
+c.v = 3
+c.y = -8
+assert c.v == 3
+assert c.y == c.a.y == c.a.b.y == -8
+assert not hasattr(c, 'b')
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy remove-frame-forcing-in-executioncontext: fix the emulator, I think

2016-03-31 Thread fijal
Author: fijal
Branch: remove-frame-forcing-in-executioncontext
Changeset: r83446:649acd9c24ea
Date: 2016-03-31 10:04 +0200
http://bitbucket.org/pypy/pypy/changeset/649acd9c24ea/

Log:fix the emulator, I think

diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -475,8 +475,6 @@
 def __call__(self):
 if self._state == 'non-forced':
 self._state = 'forced'
-elif self._state == 'invalid':
-raise InvalidVirtualRef
 return self._x
 
 @property
@@ -487,7 +485,7 @@
 
 def _finish(self):
 if self._state == 'non-forced':
-self._state = 'invalid'
+self._state = 'forgotten'
 
 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 remove-frame-forcing-in-executioncontext: close to be merged branch

2016-03-31 Thread fijal
Author: fijal
Branch: remove-frame-forcing-in-executioncontext
Changeset: r83447:6e04e357200c
Date: 2016-03-31 10:04 +0200
http://bitbucket.org/pypy/pypy/changeset/6e04e357200c/

Log:close to be merged branch

___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Merge branch that removes escaping logic in the executioncontext.

2016-03-31 Thread fijal
Author: fijal
Branch: 
Changeset: r83448:80063f19e933
Date: 2016-03-31 10:05 +0200
http://bitbucket.org/pypy/pypy/changeset/80063f19e933/

Log:Merge branch that removes escaping logic in the executioncontext.
Since introduction of jitframes, we *can* reconstruct the virtual
state much later in the program execution, after the C stack is
gone.

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -278,17 +278,9 @@
 
 def get_traceback(self):
 """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.
+accessible and inspectable by app-level Python code.
 """
-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
+return self._application_traceback
 
 def set_traceback(self, traceback):
 """Set the current traceback.  It should either be a traceback
diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -74,15 +74,6 @@
 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,7 +65,6 @@
 last_exception   = None
 f_backref= jit.vref_None
 
-escaped  = False  # see mark_as_escaped()
 debugdata= None
 
 pycode = None # code object executed by that frame
@@ -152,15 +151,6 @@
 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,7 +37,6 @@
 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,8 +475,6 @@
 def __call__(self):
 if self._state == 'non-forced':
 self._state = 'forced'
-elif self._state == 'invalid':
-raise InvalidVirtualRef
 return self._x
 
 @property
@@ -487,7 +485,7 @@
 
 def _finish(self):
 if self._state == 'non-forced':
-self._state = 'invalid'
+self._state = 'forgotten'
 
 class DirectJitVRef(DirectVRef):
 def __init__(self, x):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit