[pypy-commit] pypy ndarray-setitem-filtered: test and fix setitem for ndarrays with a boolean filter

2016-02-23 Thread mattip
Author: mattip 
Branch: ndarray-setitem-filtered
Changeset: r82466:965416239e8f
Date: 2016-02-24 08:24 +0100
http://bitbucket.org/pypy/pypy/changeset/965416239e8f/

Log:test and fix setitem for ndarrays with a boolean filter

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


[pypy-commit] pypy ndarray-setitem-filtered: WIP - add comment where the problem occurs

2016-02-23 Thread mattip
Author: mattip 
Branch: ndarray-setitem-filtered
Changeset: r82468:cae31623079d
Date: 2016-02-24 08:29 +0100
http://bitbucket.org/pypy/pypy/changeset/cae31623079d/

Log:WIP - add comment where the problem occurs

diff --git a/pypy/module/micronumpy/strides.py 
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -97,6 +97,7 @@
 # filter by axis dim
 filtr = chunks[dim]
 assert isinstance(filtr, BooleanChunk) 
+# XXX this creates a new array, and fails in setitem
 w_arr = w_arr.getitem_filter(space, filtr.w_idx, axis=dim)
 arr = w_arr.implementation
 chunks[dim] = SliceChunk(space.newslice(space.wrap(0), 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy ndarray-setitem-filtered: test, move copying to more explicit location

2016-02-23 Thread mattip
Author: mattip 
Branch: ndarray-setitem-filtered
Changeset: r82467:d995a378bdd0
Date: 2016-02-24 08:26 +0100
http://bitbucket.org/pypy/pypy/changeset/d995a378bdd0/

Log:test, move copying to more explicit location

diff --git a/pypy/module/micronumpy/concrete.py 
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -298,7 +298,14 @@
 except IndexError:
 # not a single result
 chunks = self._prepare_slice_args(space, w_index)
-return new_view(space, orig_arr, chunks)
+copy = False
+if isinstance(chunks[0], BooleanChunk):
+# numpy compatibility
+copy = True
+w_ret = new_view(space, orig_arr, chunks)
+if copy:
+w_ret = w_ret.descr_copy(space, space.wrap(w_ret.get_order()))
+return w_ret
 
 def descr_setitem(self, space, orig_arr, w_index, w_value):
 try:
diff --git a/pypy/module/micronumpy/ndarray.py 
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -22,7 +22,7 @@
 from pypy.module.micronumpy.flagsobj import W_FlagsObject
 from pypy.module.micronumpy.strides import (
 get_shape_from_iterable, shape_agreement, shape_agreement_multiple,
-is_c_contiguous, is_f_contiguous, calc_strides, new_view)
+is_c_contiguous, is_f_contiguous, calc_strides, new_view, BooleanChunk)
 from pypy.module.micronumpy.casting import can_cast_array
 from pypy.module.micronumpy.descriptor import get_dtype_cache
 
@@ -204,7 +204,13 @@
 if iter_shape is None:
 # w_index is a list of slices, return a view
 chunks = self.implementation._prepare_slice_args(space, w_index)
-return new_view(space, self, chunks)
+copy = False
+if isinstance(chunks[0], BooleanChunk):
+copy = True
+w_ret = new_view(space, self, chunks)
+if copy:
+w_ret = w_ret.descr_copy(space, space.wrap(w_ret.get_order()))
+return w_ret
 shape = res_shape + self.get_shape()[len(indexes):]
 w_res = W_NDimArray.from_shape(space, shape, self.get_dtype(),
self.get_order(), w_instance=self)
diff --git a/pypy/module/micronumpy/strides.py 
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -100,19 +100,15 @@
 w_arr = w_arr.getitem_filter(space, filtr.w_idx, axis=dim)
 arr = w_arr.implementation
 chunks[dim] = SliceChunk(space.newslice(space.wrap(0), 
- space.wrap(-1), space.w_None))
+ space.w_None, space.w_None))
 r = calculate_slice_strides(space, arr.shape, arr.start,
  arr.get_strides(), arr.get_backstrides(), chunks)
 else:
 r = calculate_slice_strides(space, arr.shape, arr.start,
  arr.get_strides(), arr.get_backstrides(), chunks)
 shape, start, strides, backstrides = r
-w_ret = W_NDimArray.new_slice(space, start, strides[:], backstrides[:],
+return W_NDimArray.new_slice(space, start, strides[:], backstrides[:],
  shape[:], arr, w_arr)
-if dim == 0:
-# Do not return a view
-return w_ret.descr_copy(space, space.wrap(w_ret.get_order()))
-return w_ret
 
 @jit.unroll_safe
 def _extend_shape(old_shape, chunks):
diff --git a/pypy/module/micronumpy/test/test_ndarray.py 
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2550,8 +2550,10 @@
 assert b.base is None
 b = a[:, np.array([True, False, True])]
 assert b.base is not None
+a[np.array([True, False]), 0] = 100
 b = a[np.array([True, False]), 0]
-assert (b ==[0]).all()
+assert b.shape == (1,)
+assert (b ==[100]).all()
 
 def test_scalar_indexing(self):
 import numpy as np
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (plan_rich, remi) fix broken commit

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82464:2feb1ca9c35c
Date: 2016-02-23 22:36 +0100
http://bitbucket.org/pypy/pypy/changeset/2feb1ca9c35c/

Log:(plan_rich,remi) fix broken commit

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -1,7 +1,7 @@
 import os
-from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken
+from rpython.jit.metainterp.history import Const, REF, JitCellToken
 from rpython.rlib.objectmodel import we_are_translated, specialize
-from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.resoperation import rop, AbstractValue
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem.lloperation import llop
 
@@ -10,7 +10,7 @@
 except ImportError:
 OrderedDict = dict # too bad
 
-class TempBox(Box):
+class TempVar(AbstractValue):
 def __init__(self):
 pass
 
@@ -267,6 +267,7 @@
 raise NotImplementedError("Purely abstract")
 
 class RegisterManager(object):
+
 """ Class that keeps track of register allocations
 """
 box_types = None   # or a list of acceptable types
@@ -292,19 +293,19 @@
 def is_still_alive(self, v):
 # Check if 'v' is alive at the current position.
 # Return False if the last usage is strictly before.
-return self.longevity[v][1] >= self.position
+return self.longevity.last_use(v) >= self.position
 
 def stays_alive(self, v):
 # Check if 'v' stays alive after the current position.
 # Return False if the last usage is before or at position.
-return self.longevity[v][1] > self.position
+return self.longevity.last_use(v) > self.position
 
 def next_instruction(self, incr=1):
 self.position += incr
 
 def _check_type(self, v):
 if not we_are_translated() and self.box_types is not None:
-assert isinstance(v, TempBox) or v.type in self.box_types
+assert isinstance(v, TempVar) or v.type in self.box_types
 
 def possibly_free_var(self, v):
 """ If v is stored in a register and v is not used beyond the
@@ -314,7 +315,7 @@
 self._check_type(v)
 if isinstance(v, Const):
 return
-if v not in self.longevity or self.longevity[v][1] <= self.position:
+if not self.longevity.exists(v) or self.longevity.last_use(v) <= 
self.position:
 if v in self.reg_bindings:
 self.free_regs.append(self.reg_bindings[v])
 del self.reg_bindings[v]
@@ -348,7 +349,7 @@
 assert len(self.temp_boxes) == 0
 if self.longevity:
 for v in self.reg_bindings:
-assert self.longevity[v][1] > self.position
+assert self.longevity.last_use(v) > self.position
 
 def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
 """ Try to allocate a register, if we have one free.
@@ -424,7 +425,7 @@
 continue
 if need_lower_byte and reg in self.no_lower_byte_regs:
 continue
-max_age = self.longevity[next][1]
+max_age = self.longevity.last_use(next)
 if cur_max_age < max_age:
 cur_max_age = max_age
 candidate = next
@@ -442,8 +443,8 @@
 Will not spill a variable from 'forbidden_vars'.
 """
 self._check_type(v)
-if isinstance(v, TempBox):
-self.longevity[v] = (self.position, self.position)
+if isinstance(v, TempVar):
+self.longevity.new_live_range(v, self.position, self.position)
 loc = self.try_allocate_reg(v, selected_reg,
 need_lower_byte=need_lower_byte)
 if loc:
@@ -553,13 +554,14 @@
 loc = self.force_allocate_reg(v, forbidden_vars)
 self.assembler.regalloc_mov(prev_loc, loc)
 assert v in self.reg_bindings
-if self.longevity[v][1] > self.position:
+if self.longevity.last_use(v) > self.position:
 # we need to find a new place for variable v and
 # store result in the same place
 loc = self.reg_bindings[v]
 del self.reg_bindings[v]
-if self.frame_manager.get(v) is None:
+if self.frame_manager.get(v) is None or self.free_regs:
 self._move_variable_away(v, loc)
+
 self.reg_bindings[result_v] = loc
 else:
 self._reallocate_from_to(v, result_v)
@@ -581,7 +583,7 @@
 1 (save all), or 2 (save default+PTRs).
 """
 for v, reg in self.reg_bindings.items():
-if v not in force_store and self.longevity[v][1] <= self.position:
+if v not in force_store and self.longevity.last_use(v) <= 
self.position:

[pypy-commit] pypy fix-longevity: rename to distinguish LiveRange objs from longevity dicts

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82465:449462f0839e
Date: 2016-02-23 22:38 +0100
http://bitbucket.org/pypy/pypy/changeset/449462f0839e/

Log:rename to distinguish LiveRange objs from longevity dicts

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -276,10 +276,10 @@
 save_around_call_regs = []
 frame_reg = None
 
-def __init__(self, longevity, frame_manager=None, assembler=None):
+def __init__(self, live_ranges, frame_manager=None, assembler=None):
 self.free_regs = self.all_regs[:]
 self.free_regs.reverse()
-self.longevity = longevity
+self.live_ranges = live_ranges
 self.temp_boxes = []
 if not we_are_translated():
 self.reg_bindings = OrderedDict()
@@ -293,12 +293,12 @@
 def is_still_alive(self, v):
 # Check if 'v' is alive at the current position.
 # Return False if the last usage is strictly before.
-return self.longevity.last_use(v) >= self.position
+return self.live_ranges.last_use(v) >= self.position
 
 def stays_alive(self, v):
 # Check if 'v' stays alive after the current position.
 # Return False if the last usage is before or at position.
-return self.longevity.last_use(v) > self.position
+return self.live_ranges.last_use(v) > self.position
 
 def next_instruction(self, incr=1):
 self.position += incr
@@ -315,7 +315,7 @@
 self._check_type(v)
 if isinstance(v, Const):
 return
-if not self.longevity.exists(v) or self.longevity.last_use(v) <= 
self.position:
+if not self.live_ranges.exists(v) or self.live_ranges.last_use(v) <= 
self.position:
 if v in self.reg_bindings:
 self.free_regs.append(self.reg_bindings[v])
 del self.reg_bindings[v]
@@ -347,9 +347,9 @@
 else:
 assert len(self.reg_bindings) + len(self.free_regs) == 
len(self.all_regs)
 assert len(self.temp_boxes) == 0
-if self.longevity:
+if self.live_ranges:
 for v in self.reg_bindings:
-assert self.longevity.last_use(v) > self.position
+assert self.live_ranges.last_use(v) > self.position
 
 def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
 """ Try to allocate a register, if we have one free.
@@ -425,7 +425,7 @@
 continue
 if need_lower_byte and reg in self.no_lower_byte_regs:
 continue
-max_age = self.longevity.last_use(next)
+max_age = self.live_ranges.last_use(next)
 if cur_max_age < max_age:
 cur_max_age = max_age
 candidate = next
@@ -444,7 +444,7 @@
 """
 self._check_type(v)
 if isinstance(v, TempVar):
-self.longevity.new_live_range(v, self.position, self.position)
+self.live_ranges.new_live_range(v, self.position, self.position)
 loc = self.try_allocate_reg(v, selected_reg,
 need_lower_byte=need_lower_byte)
 if loc:
@@ -554,7 +554,7 @@
 loc = self.force_allocate_reg(v, forbidden_vars)
 self.assembler.regalloc_mov(prev_loc, loc)
 assert v in self.reg_bindings
-if self.longevity.last_use(v) > self.position:
+if self.live_ranges.last_use(v) > self.position:
 # we need to find a new place for variable v and
 # store result in the same place
 loc = self.reg_bindings[v]
@@ -583,7 +583,7 @@
 1 (save all), or 2 (save default+PTRs).
 """
 for v, reg in self.reg_bindings.items():
-if v not in force_store and self.longevity.last_use(v) <= 
self.position:
+if v not in force_store and self.live_ranges.last_use(v) <= 
self.position:
 # variable dies
 del self.reg_bindings[v]
 self.free_regs.append(reg)
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
@@ -515,7 +515,7 @@
 # and won't be used after the current operation finishes,
 # then swap the role of 'x' and 'y'
 if (symm and isinstance(argloc, RegLoc) and
-self.rm.longevity.last_use(y) == self.rm.position):
+self.rm.live_ranges.last_use(y) == self.rm.position):
 x, y = y, x
 argloc = self.loc(y)
 #
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.3: hg merge py3k

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: py3.3
Changeset: r82463:a21adf0cd8fd
Date: 2016-02-23 22:43 +0100
http://bitbucket.org/pypy/pypy/changeset/a21adf0cd8fd/

Log:hg merge py3k

diff too long, truncating to 2000 out of 5520 lines

diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -8,6 +8,7 @@
 content = fid.read()
 # from cffi's Verifier()
 key = '\x00'.join([sys.version[:3], content])
+key += 'cpyext-gc-support-2'   # this branch requires recompilation!
 if sys.version_info >= (3,):
 key = key.encode('utf-8')
 k1 = hex(binascii.crc32(key[0::2]) & 0x)
diff --git a/pypy/doc/discussion/rawrefcount.rst 
b/pypy/doc/discussion/rawrefcount.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussion/rawrefcount.rst
@@ -0,0 +1,158 @@
+==
+Rawrefcount and the GC
+==
+
+
+GC Interface
+
+
+"PyObject" is a raw structure with at least two fields, ob_refcnt and
+ob_pypy_link.  The ob_refcnt is the reference counter as used on
+CPython.  If the PyObject structure is linked to a live PyPy object,
+its current address is stored in ob_pypy_link and ob_refcnt is bumped
+by either the constant REFCNT_FROM_PYPY, or the constant
+REFCNT_FROM_PYPY_LIGHT (== REFCNT_FROM_PYPY + SOME_HUGE_VALUE)
+(to mean "light finalizer").
+
+Most PyPy objects exist outside cpyext, and conversely in cpyext it is
+possible that a lot of PyObjects exist without being seen by the rest
+of PyPy.  At the interface, however, we can "link" a PyPy object and a
+PyObject.  There are two kinds of link:
+
+rawrefcount.create_link_pypy(p, ob)
+
+Makes a link between an exising object gcref 'p' and a newly
+allocated PyObject structure 'ob'.  ob->ob_refcnt must be
+initialized to either REFCNT_FROM_PYPY, or
+REFCNT_FROM_PYPY_LIGHT.  (The second case is an optimization:
+when the GC finds the PyPy object and PyObject no longer
+referenced, it can just free() the PyObject.)
+
+rawrefcount.create_link_pyobj(p, ob)
+
+Makes a link from an existing PyObject structure 'ob' to a newly
+allocated W_CPyExtPlaceHolderObject 'p'.  You must also add
+REFCNT_FROM_PYPY to ob->ob_refcnt.  For cases where the PyObject
+contains all the data, and the PyPy object is just a proxy.  The
+W_CPyExtPlaceHolderObject should have only a field that contains
+the address of the PyObject, but that's outside the scope of the
+GC.
+
+rawrefcount.from_obj(p)
+
+If there is a link from object 'p' made with create_link_pypy(),
+returns the corresponding 'ob'.  Otherwise, returns NULL.
+
+rawrefcount.to_obj(Class, ob)
+
+Returns ob->ob_pypy_link, cast to an instance of 'Class'.
+
+
+Collection logic
+
+
+Objects existing purely on the C side have ob->ob_pypy_link == 0;
+these are purely reference counted.  On the other hand, if
+ob->ob_pypy_link != 0, then ob->ob_refcnt is at least REFCNT_FROM_PYPY
+and the object is part of a "link".
+
+The idea is that links whose 'p' is not reachable from other PyPy
+objects *and* whose 'ob->ob_refcnt' is REFCNT_FROM_PYPY or
+REFCNT_FROM_PYPY_LIGHT are the ones who die.  But it is more messy
+because PyObjects still (usually) need to have a tp_dealloc called,
+and this cannot occur immediately (and can do random things like
+accessing other references this object points to, or resurrecting the
+object).
+
+Let P = list of links created with rawrefcount.create_link_pypy()
+and O = list of links created with rawrefcount.create_link_pyobj().
+The PyPy objects in the list O are all W_CPyExtPlaceHolderObject: all
+the data is in the PyObjects, and all outsite references (if any) are
+in C, as "PyObject *" fields.
+
+So, during the collection we do this about P links:
+
+for (p, ob) in P:
+if ob->ob_refcnt != REFCNT_FROM_PYPY
+   and ob->ob_refcnt != REFCNT_FROM_PYPY_LIGHT:
+mark 'p' as surviving, as well as all its dependencies
+
+At the end of the collection, the P and O links are both handled like
+this:
+
+for (p, ob) in P + O:
+if p is not surviving:# even if 'ob' might be surviving
+unlink p and ob
+if ob->ob_refcnt == REFCNT_FROM_PYPY_LIGHT:
+free(ob)
+elif ob->ob_refcnt > REFCNT_FROM_PYPY_LIGHT:
+ob->ob_refcnt -= REFCNT_FROM_PYPY_LIGHT
+else:
+ob->ob_refcnt -= REFCNT_FROM_PYPY
+if ob->ob_refcnt == 0:
+invoke _Py_Dealloc(ob) later, outside the GC
+
+
+GC Implementation
+-
+
+We need two copies of both the P list and O list, for young or old
+objects.  All four lists can be regular AddressLists of 'ob' objects.
+
+We also need an AddressDict mapping 'p' to 'ob' for all links in the P
+list, and update it when PyPy objects move.
+
+
+Further notes
+-
+
+XXX
+XXX the 

[pypy-commit] pypy py3k: hg merge 1df21a900a84

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: py3k
Changeset: r82461:fa1b4e83847a
Date: 2016-02-23 16:59 +0100
http://bitbucket.org/pypy/pypy/changeset/fa1b4e83847a/

Log:hg merge 1df21a900a84

diff --git a/pypy/module/cpyext/bytesobject.py 
b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -8,7 +8,6 @@
 PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
 make_typedescr, get_typedescr)
 
-
 ##
 ## Implementation of PyBytesObject
 ## 
@@ -144,8 +143,6 @@
 ref_str.c_buffer = rffi.str2charp(s)
 return ref_str.c_buffer
 
-#___
-
 @cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], 
rffi.INT_real, error=-1)
 def PyBytes_AsStringAndSize(space, ref, buffer, length):
 if not PyBytes_Check(space, ref):
@@ -228,9 +225,9 @@
 
 if w_newpart is None or not PyBytes_Check(space, ref[0]) or \
 not PyBytes_Check(space, w_newpart):
- Py_DecRef(space, ref[0])
- ref[0] = lltype.nullptr(PyObject.TO)
- return
+Py_DecRef(space, ref[0])
+ref[0] = lltype.nullptr(PyObject.TO)
+return
 w_str = from_ref(space, ref[0])
 w_newstr = space.add(w_str, w_newpart)
 Py_DecRef(space, ref[0])
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: hg merge default

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: py3k
Changeset: r82462:842942cabb34
Date: 2016-02-23 22:26 +0100
http://bitbucket.org/pypy/pypy/changeset/842942cabb34/

Log:hg merge default

diff too long, truncating to 2000 out of 5375 lines

diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -7,6 +7,7 @@
 content = fid.read()
 # from cffi's Verifier()
 key = '\x00'.join([sys.version[:3], content])
+key += 'cpyext-gc-support-2'   # this branch requires recompilation!
 if sys.version_info >= (3,):
 key = key.encode('utf-8')
 k1 = hex(binascii.crc32(key[0::2]) & 0x)
diff --git a/pypy/doc/discussion/rawrefcount.rst 
b/pypy/doc/discussion/rawrefcount.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussion/rawrefcount.rst
@@ -0,0 +1,158 @@
+==
+Rawrefcount and the GC
+==
+
+
+GC Interface
+
+
+"PyObject" is a raw structure with at least two fields, ob_refcnt and
+ob_pypy_link.  The ob_refcnt is the reference counter as used on
+CPython.  If the PyObject structure is linked to a live PyPy object,
+its current address is stored in ob_pypy_link and ob_refcnt is bumped
+by either the constant REFCNT_FROM_PYPY, or the constant
+REFCNT_FROM_PYPY_LIGHT (== REFCNT_FROM_PYPY + SOME_HUGE_VALUE)
+(to mean "light finalizer").
+
+Most PyPy objects exist outside cpyext, and conversely in cpyext it is
+possible that a lot of PyObjects exist without being seen by the rest
+of PyPy.  At the interface, however, we can "link" a PyPy object and a
+PyObject.  There are two kinds of link:
+
+rawrefcount.create_link_pypy(p, ob)
+
+Makes a link between an exising object gcref 'p' and a newly
+allocated PyObject structure 'ob'.  ob->ob_refcnt must be
+initialized to either REFCNT_FROM_PYPY, or
+REFCNT_FROM_PYPY_LIGHT.  (The second case is an optimization:
+when the GC finds the PyPy object and PyObject no longer
+referenced, it can just free() the PyObject.)
+
+rawrefcount.create_link_pyobj(p, ob)
+
+Makes a link from an existing PyObject structure 'ob' to a newly
+allocated W_CPyExtPlaceHolderObject 'p'.  You must also add
+REFCNT_FROM_PYPY to ob->ob_refcnt.  For cases where the PyObject
+contains all the data, and the PyPy object is just a proxy.  The
+W_CPyExtPlaceHolderObject should have only a field that contains
+the address of the PyObject, but that's outside the scope of the
+GC.
+
+rawrefcount.from_obj(p)
+
+If there is a link from object 'p' made with create_link_pypy(),
+returns the corresponding 'ob'.  Otherwise, returns NULL.
+
+rawrefcount.to_obj(Class, ob)
+
+Returns ob->ob_pypy_link, cast to an instance of 'Class'.
+
+
+Collection logic
+
+
+Objects existing purely on the C side have ob->ob_pypy_link == 0;
+these are purely reference counted.  On the other hand, if
+ob->ob_pypy_link != 0, then ob->ob_refcnt is at least REFCNT_FROM_PYPY
+and the object is part of a "link".
+
+The idea is that links whose 'p' is not reachable from other PyPy
+objects *and* whose 'ob->ob_refcnt' is REFCNT_FROM_PYPY or
+REFCNT_FROM_PYPY_LIGHT are the ones who die.  But it is more messy
+because PyObjects still (usually) need to have a tp_dealloc called,
+and this cannot occur immediately (and can do random things like
+accessing other references this object points to, or resurrecting the
+object).
+
+Let P = list of links created with rawrefcount.create_link_pypy()
+and O = list of links created with rawrefcount.create_link_pyobj().
+The PyPy objects in the list O are all W_CPyExtPlaceHolderObject: all
+the data is in the PyObjects, and all outsite references (if any) are
+in C, as "PyObject *" fields.
+
+So, during the collection we do this about P links:
+
+for (p, ob) in P:
+if ob->ob_refcnt != REFCNT_FROM_PYPY
+   and ob->ob_refcnt != REFCNT_FROM_PYPY_LIGHT:
+mark 'p' as surviving, as well as all its dependencies
+
+At the end of the collection, the P and O links are both handled like
+this:
+
+for (p, ob) in P + O:
+if p is not surviving:# even if 'ob' might be surviving
+unlink p and ob
+if ob->ob_refcnt == REFCNT_FROM_PYPY_LIGHT:
+free(ob)
+elif ob->ob_refcnt > REFCNT_FROM_PYPY_LIGHT:
+ob->ob_refcnt -= REFCNT_FROM_PYPY_LIGHT
+else:
+ob->ob_refcnt -= REFCNT_FROM_PYPY
+if ob->ob_refcnt == 0:
+invoke _Py_Dealloc(ob) later, outside the GC
+
+
+GC Implementation
+-
+
+We need two copies of both the P list and O list, for young or old
+objects.  All four lists can be regular AddressLists of 'ob' objects.
+
+We also need an AddressDict mapping 'p' to 'ob' for all links in the P
+list, and update it when PyPy objects move.
+
+
+Further notes
+-
+
+XXX
+XXX 

[pypy-commit] pypy fix-longevity: (remi, plan_rich) refactored free_reg into two lists (caller saved and callee saved list)

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82460:98153a101dda
Date: 2016-02-23 19:09 +0100
http://bitbucket.org/pypy/pypy/changeset/98153a101dda/

Log:(remi, plan_rich) refactored free_reg into two lists (caller saved
and callee saved list)

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -1,7 +1,7 @@
 import os
-from rpython.jit.metainterp.history import Const, REF, JitCellToken
+from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken
 from rpython.rlib.objectmodel import we_are_translated, specialize
-from rpython.jit.metainterp.resoperation import rop, AbstractValue
+from rpython.jit.metainterp.resoperation import rop
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem.lloperation import llop
 
@@ -10,7 +10,7 @@
 except ImportError:
 OrderedDict = dict # too bad
 
-class TempVar(AbstractValue):
+class TempBox(Box):
 def __init__(self):
 pass
 
@@ -267,7 +267,6 @@
 raise NotImplementedError("Purely abstract")
 
 class RegisterManager(object):
-
 """ Class that keeps track of register allocations
 """
 box_types = None   # or a list of acceptable types
@@ -276,10 +275,10 @@
 save_around_call_regs = []
 frame_reg = None
 
-def __init__(self, live_ranges, frame_manager=None, assembler=None):
+def __init__(self, longevity, frame_manager=None, assembler=None):
 self.free_regs = self.all_regs[:]
 self.free_regs.reverse()
-self.live_ranges = live_ranges
+self.longevity = longevity
 self.temp_boxes = []
 if not we_are_translated():
 self.reg_bindings = OrderedDict()
@@ -293,19 +292,19 @@
 def is_still_alive(self, v):
 # Check if 'v' is alive at the current position.
 # Return False if the last usage is strictly before.
-return self.live_ranges.last_use(v) >= self.position
+return self.longevity[v][1] >= self.position
 
 def stays_alive(self, v):
 # Check if 'v' stays alive after the current position.
 # Return False if the last usage is before or at position.
-return self.live_ranges.last_use(v) > self.position
+return self.longevity[v][1] > self.position
 
 def next_instruction(self, incr=1):
 self.position += incr
 
 def _check_type(self, v):
 if not we_are_translated() and self.box_types is not None:
-assert isinstance(v, TempVar) or v.type in self.box_types
+assert isinstance(v, TempBox) or v.type in self.box_types
 
 def possibly_free_var(self, v):
 """ If v is stored in a register and v is not used beyond the
@@ -315,7 +314,7 @@
 self._check_type(v)
 if isinstance(v, Const):
 return
-if not self.live_ranges.exists(v) or self.live_ranges.last_use(v) <= 
self.position:
+if v not in self.longevity or self.longevity[v][1] <= self.position:
 if v in self.reg_bindings:
 self.free_regs.append(self.reg_bindings[v])
 del self.reg_bindings[v]
@@ -347,9 +346,9 @@
 else:
 assert len(self.reg_bindings) + len(self.free_regs) == 
len(self.all_regs)
 assert len(self.temp_boxes) == 0
-if self.live_ranges.longevity:
+if self.longevity:
 for v in self.reg_bindings:
-assert self.live_ranges.last_use(v) > self.position
+assert self.longevity[v][1] > self.position
 
 def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
 """ Try to allocate a register, if we have one free.
@@ -425,7 +424,7 @@
 continue
 if need_lower_byte and reg in self.no_lower_byte_regs:
 continue
-max_age = self.live_ranges.last_use(next)
+max_age = self.longevity[next][1]
 if cur_max_age < max_age:
 cur_max_age = max_age
 candidate = next
@@ -443,8 +442,8 @@
 Will not spill a variable from 'forbidden_vars'.
 """
 self._check_type(v)
-if isinstance(v, TempVar):
-self.live_ranges.new_live_range(v, self.position, self.position)
+if isinstance(v, TempBox):
+self.longevity[v] = (self.position, self.position)
 loc = self.try_allocate_reg(v, selected_reg,
 need_lower_byte=need_lower_byte)
 if loc:
@@ -554,14 +553,13 @@
 loc = self.force_allocate_reg(v, forbidden_vars)
 self.assembler.regalloc_mov(prev_loc, loc)
 assert v in self.reg_bindings
-if self.live_ranges.last_use(v) > self.position:
+if self.longevity[v][1] > self.position:
 # we need to find a new place 

[pypy-commit] pypy default: transplant sensible parts of 6ed007073e26;

2016-02-23 Thread fijal
Author: fijal
Branch: 
Changeset: r82459:7d17d8205bfd
Date: 2016-02-23 18:39 +0100
http://bitbucket.org/pypy/pypy/changeset/7d17d8205bfd/

Log:transplant sensible parts of 6ed007073e26;

diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -41,29 +41,29 @@
   Amaury Forgeot d'Arc
   Antonio Cuni
   Samuele Pedroni
+  Matti Picus
   Alex Gaynor
   Brian Kearns
-  Matti Picus
   Philip Jenvey
   Michael Hudson
+  Ronan Lamy
   David Schneider
+  Manuel Jacob
   Holger Krekel
   Christian Tismer
   Hakan Ardo
-  Manuel Jacob
-  Ronan Lamy
   Benjamin Peterson
+  Richard Plangger
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
-  Richard Plangger
   Richard Emslie
   Alexander Schremmer
   Dan Villiom Podlaski Christiansen
+  Remi Meier
   Lukas Diekmann
   Sven Hager
   Anders Lehmann
-  Remi Meier
   Aurelien Campeas
   Niklaus Haldimann
   Camillo Bruni
@@ -72,8 +72,8 @@
   Romain Guillebert
   Leonardo Santagada
   Seo Sanghyeon
+  Ronny Pfannschmidt
   Justin Peel
-  Ronny Pfannschmidt
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
@@ -95,6 +95,7 @@
   Tyler Wade
   Michael Foord
   Stephan Diehl
+  Vincent Legoll
   Stefan Schwarzer
   Valentino Volonghi
   Tomek Meka
@@ -105,9 +106,9 @@
   Jean-Paul Calderone
   Timo Paulssen
   Squeaky
+  Marius Gedminas
   Alexandre Fayolle
   Simon Burton
-  Marius Gedminas
   Martin Matusiak
   Konstantin Lopuhin
   Wenzhu Man
@@ -116,16 +117,20 @@
   Ivan Sichmann Freitas
   Greg Price
   Dario Bertini
+  Stefano Rivera
   Mark Pearse
   Simon Cross
   Andreas Sthrk
-  Stefano Rivera
+  Edd Barrett
   Jean-Philippe St. Pierre
   Guido van Rossum
   Pavel Vinogradov
+  Jeremy Thurgood
   Pawe Piotr Przeradowski
+  Spenser Bauman
   Paul deGrandis
   Ilya Osadchiy
+  marky1991
   Tobias Oberstein
   Adrian Kuhn
   Boris Feigin
@@ -134,14 +139,12 @@
   Georg Brandl
   Bert Freudenberg
   Stian Andreassen
-  Edd Barrett
+  Tobias Pape
   Wanja Saatkamp
   Gerald Klix
   Mike Blume
-  Tobias Pape
   Oscar Nierstrasz
   Stefan H. Muller
-  Jeremy Thurgood
   Rami Chowdhury
   Eugene Oden
   Henry Mason
@@ -153,6 +156,8 @@
   Lukas Renggli
   Guenter Jantzen
   Ned Batchelder
+  Tim Felgentreff
+  Anton Gulenko
   Amit Regmi
   Ben Young
   Nicolas Chauvat
@@ -162,12 +167,12 @@
   Nicholas Riley
   Jason Chu
   Igor Trindade Oliveira
-  Tim Felgentreff
+  Yichao Yu
   Rocco Moretti
   Gintautas Miliauskas
   Michael Twomey
   Lucian Branescu Mihaila
-  Yichao Yu
+  Devin Jeanpierre
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
@@ -191,33 +196,33 @@
   Stanislaw Halik
   Mikael Schnenberg
   Berkin Ilbeyi
-  Elmo M?ntynen
+  Elmo Mntynen
+  Faye Zhao
   Jonathan David Riehl
   Anders Qvist
   Corbin Simpson
   Chirag Jadwani
   Beatrice During
   Alex Perry
-  Vincent Legoll
+  Vaibhav Sood
   Alan McIntyre
-  Spenser Bauman
+  William Leslie
   Alexander Sedov
   Attila Gobi
+  Jasper.Schulz
   Christopher Pope
-  Devin Jeanpierre
-  Vaibhav Sood
   Christian Tismer 
   Marc Abramowitz
   Dan Stromberg
   Arjun Naik
   Valentina Mukhamedzhanova
   Stefano Parmesan
+  Mark Young
   Alexis Daboville
   Jens-Uwe Mager
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
-  Anton Gulenko
   Gabriel
   Lukas Vacek
   Andrew Dalke
@@ -225,6 +230,7 @@
   Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
+  Omer Katz
   Jacek Generowicz
   Alejandro J. Cura
   Jacob Oscarson
@@ -239,6 +245,7 @@
   Lars Wassermann
   Philipp Rustemeuer
   Henrik Vendelbo
+  Richard Lancaster
   Dan Buch
   Miguel de Val Borro
   Artur Lisiecki
@@ -250,18 +257,18 @@
   Tomo Cocoa
   Kim Jin Su
   Toni Mattis
+  Amber Brown
   Lucas Stadler
   Julian Berman
   Markus Holtermann
   roberto@goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
-  William Leslie
   Bobby Impollonia
-  Faye Zhao
   t...@eistee.fritz.box
   Andrew Thompson
   Yusei Tahara
+  Aaron Tubbs
   Ben Darnell
   Roberto De Ioris
   Juan Francisco Cantero Hurtado
@@ -273,6 +280,7 @@
   Christopher Armstrong
   Michael Hudson-Doyle
   Anders Sigfridsson
+  Nikolay Zinov
   Yasir Suhail
   Jason Michalski
   rafalgalczyn...@gmail.com
@@ -282,6 +290,7 @@
   Gustavo Niemeyer
   Stephan Busemann
   Rafa Gaczyski
+  Matt Bogosian
   Christian Muirhead
   Berker Peksag
   James Lan
@@ -316,9 +325,9 @@
   Stefan Marr
   jiaaro
   Mads Kiilerich
-  Richard Lancaster
   opassembler.py
   Antony Lee
+  Jason Madden
   Yaroslav Fedevych
   Jim Hunziker
   Markus Unterwaditzer
@@ -327,6 +336,7 @@
   squeaky
   Zearin
   soareschen
+  Jonas Pfannschmidt
   Kurt Griffiths
   Mike Bayer
   Matthew Miller
diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py
--- a/pypy/doc/tool/makecontributor.py
+++ b/pypy/doc/tool/makecontributor.py
@@ -72,6 +72,7 @@
 'Anton Gulenko':['anton gulenko', 'anton_gulenko'],
 'Richard Lancaster':['richardlancaster'],
 'William Leslie':['William ML Leslie'],
+'Spenser Bauman':['Spenser Andrew Bauman'],
 }
 
 alias_map = {}

[pypy-commit] pypy statistics-maps: update contributor list

2016-02-23 Thread cfbolz
Author: Carl Friedrich Bolz 
Branch: statistics-maps
Changeset: r82458:6ed007073e26
Date: 2016-02-23 18:32 +0100
http://bitbucket.org/pypy/pypy/changeset/6ed007073e26/

Log:update contributor list

diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -41,29 +41,29 @@
   Amaury Forgeot d'Arc
   Antonio Cuni
   Samuele Pedroni
+  Matti Picus
   Alex Gaynor
   Brian Kearns
-  Matti Picus
   Philip Jenvey
   Michael Hudson
+  Ronan Lamy
   David Schneider
+  Manuel Jacob
   Holger Krekel
   Christian Tismer
   Hakan Ardo
-  Manuel Jacob
-  Ronan Lamy
   Benjamin Peterson
+  Richard Plangger
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
-  Richard Plangger
   Richard Emslie
   Alexander Schremmer
   Dan Villiom Podlaski Christiansen
+  Remi Meier
   Lukas Diekmann
   Sven Hager
   Anders Lehmann
-  Remi Meier
   Aurelien Campeas
   Niklaus Haldimann
   Camillo Bruni
@@ -72,8 +72,8 @@
   Romain Guillebert
   Leonardo Santagada
   Seo Sanghyeon
+  Ronny Pfannschmidt
   Justin Peel
-  Ronny Pfannschmidt
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
@@ -95,6 +95,7 @@
   Tyler Wade
   Michael Foord
   Stephan Diehl
+  Vincent Legoll
   Stefan Schwarzer
   Valentino Volonghi
   Tomek Meka
@@ -105,9 +106,9 @@
   Jean-Paul Calderone
   Timo Paulssen
   Squeaky
+  Marius Gedminas
   Alexandre Fayolle
   Simon Burton
-  Marius Gedminas
   Martin Matusiak
   Konstantin Lopuhin
   Wenzhu Man
@@ -116,16 +117,20 @@
   Ivan Sichmann Freitas
   Greg Price
   Dario Bertini
+  Stefano Rivera
   Mark Pearse
   Simon Cross
   Andreas Sthrk
-  Stefano Rivera
+  Edd Barrett
   Jean-Philippe St. Pierre
   Guido van Rossum
   Pavel Vinogradov
+  Jeremy Thurgood
   Pawe Piotr Przeradowski
+  Spenser Bauman
   Paul deGrandis
   Ilya Osadchiy
+  marky1991
   Tobias Oberstein
   Adrian Kuhn
   Boris Feigin
@@ -134,14 +139,12 @@
   Georg Brandl
   Bert Freudenberg
   Stian Andreassen
-  Edd Barrett
+  Tobias Pape
   Wanja Saatkamp
   Gerald Klix
   Mike Blume
-  Tobias Pape
   Oscar Nierstrasz
   Stefan H. Muller
-  Jeremy Thurgood
   Rami Chowdhury
   Eugene Oden
   Henry Mason
@@ -153,6 +156,8 @@
   Lukas Renggli
   Guenter Jantzen
   Ned Batchelder
+  Tim Felgentreff
+  Anton Gulenko
   Amit Regmi
   Ben Young
   Nicolas Chauvat
@@ -162,12 +167,12 @@
   Nicholas Riley
   Jason Chu
   Igor Trindade Oliveira
-  Tim Felgentreff
+  Yichao Yu
   Rocco Moretti
   Gintautas Miliauskas
   Michael Twomey
   Lucian Branescu Mihaila
-  Yichao Yu
+  Devin Jeanpierre
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
@@ -191,33 +196,33 @@
   Stanislaw Halik
   Mikael Schnenberg
   Berkin Ilbeyi
-  Elmo M?ntynen
+  Elmo Mntynen
+  Faye Zhao
   Jonathan David Riehl
   Anders Qvist
   Corbin Simpson
   Chirag Jadwani
   Beatrice During
   Alex Perry
-  Vincent Legoll
+  Vaibhav Sood
   Alan McIntyre
-  Spenser Bauman
+  William Leslie
   Alexander Sedov
   Attila Gobi
+  Jasper.Schulz
   Christopher Pope
-  Devin Jeanpierre
-  Vaibhav Sood
   Christian Tismer 
   Marc Abramowitz
   Dan Stromberg
   Arjun Naik
   Valentina Mukhamedzhanova
   Stefano Parmesan
+  Mark Young
   Alexis Daboville
   Jens-Uwe Mager
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
-  Anton Gulenko
   Gabriel
   Lukas Vacek
   Andrew Dalke
@@ -225,6 +230,7 @@
   Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
+  Omer Katz
   Jacek Generowicz
   Alejandro J. Cura
   Jacob Oscarson
@@ -239,6 +245,7 @@
   Lars Wassermann
   Philipp Rustemeuer
   Henrik Vendelbo
+  Richard Lancaster
   Dan Buch
   Miguel de Val Borro
   Artur Lisiecki
@@ -250,18 +257,18 @@
   Tomo Cocoa
   Kim Jin Su
   Toni Mattis
+  Amber Brown
   Lucas Stadler
   Julian Berman
   Markus Holtermann
   roberto@goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
-  William Leslie
   Bobby Impollonia
-  Faye Zhao
   t...@eistee.fritz.box
   Andrew Thompson
   Yusei Tahara
+  Aaron Tubbs
   Ben Darnell
   Roberto De Ioris
   Juan Francisco Cantero Hurtado
@@ -273,6 +280,7 @@
   Christopher Armstrong
   Michael Hudson-Doyle
   Anders Sigfridsson
+  Nikolay Zinov
   Yasir Suhail
   Jason Michalski
   rafalgalczyn...@gmail.com
@@ -282,6 +290,7 @@
   Gustavo Niemeyer
   Stephan Busemann
   Rafa Gaczyski
+  Matt Bogosian
   Christian Muirhead
   Berker Peksag
   James Lan
@@ -316,9 +325,9 @@
   Stefan Marr
   jiaaro
   Mads Kiilerich
-  Richard Lancaster
   opassembler.py
   Antony Lee
+  Jason Madden
   Yaroslav Fedevych
   Jim Hunziker
   Markus Unterwaditzer
@@ -327,6 +336,7 @@
   squeaky
   Zearin
   soareschen
+  Jonas Pfannschmidt
   Kurt Griffiths
   Mike Bayer
   Matthew Miller
diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py
--- a/pypy/doc/tool/makecontributor.py
+++ b/pypy/doc/tool/makecontributor.py
@@ -72,6 +72,7 @@
 'Anton Gulenko':['anton gulenko', 'anton_gulenko'],
 'Richard Lancaster':['richardlancaster'],
 'William Leslie':['William ML Leslie'],
+'Spenser Bauman':['Spenser Andrew Bauman'],
 }
 
 

[pypy-commit] pypy default: bump the years

2016-02-23 Thread fijal
Author: fijal
Branch: 
Changeset: r82457:39e6f53a3270
Date: 2016-02-23 18:22 +0100
http://bitbucket.org/pypy/pypy/changeset/39e6f53a3270/

Log:bump the years

diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py
--- a/pypy/module/sys/app.py
+++ b/pypy/module/sys/app.py
@@ -70,11 +70,11 @@
 return None
 
 copyright_str = """
-Copyright 2003-2014 PyPy development team.
+Copyright 2003-2016 PyPy development team.
 All Rights Reserved.
 For further information, see 
 
-Portions Copyright (c) 2001-2014 Python Software Foundation.
+Portions Copyright (c) 2001-2016 Python Software Foundation.
 All Rights Reserved.
 
 Portions Copyright (c) 2000 BeOpen.com.
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: look inside tuple hash, improves mdp

2016-02-23 Thread fijal
Author: fijal
Branch: 
Changeset: r82456:3c94bed8d07e
Date: 2016-02-23 18:20 +0100
http://bitbucket.org/pypy/pypy/changeset/3c94bed8d07e/

Log:look inside tuple hash, improves mdp

diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -30,6 +30,11 @@
 contains_jmp = jit.JitDriver(greens = ['tp'], reds = 'auto',
  name = 'tuple.contains')
 
+hash_driver = jit.JitDriver(
+name='tuple.hash',
+greens=['w_type'],
+reds='auto')
+
 class W_AbstractTupleObject(W_Root):
 __slots__ = ()
 
@@ -262,8 +267,14 @@
 def length(self):
 return len(self.wrappeditems)
 
-@jit.look_inside_iff(lambda self, _1: _unroll_condition(self))
 def descr_hash(self, space):
+if _unroll_condition(self):
+return self._descr_hash_unroll(space)
+else:
+return self._descr_hash_jitdriver(space)
+
+@jit.unroll_safe
+def _descr_hash_unroll(self, space):
 mult = 103
 x = 0x345678
 z = len(self.wrappeditems)
@@ -275,6 +286,20 @@
 x += 97531
 return space.wrap(intmask(x))
 
+def _descr_hash_jitdriver(self, space):
+mult = 103
+x = 0x345678
+z = len(self.wrappeditems)
+w_type = space.type(self.wrappeditems[0])
+for w_item in self.wrappeditems:
+hash_driver.jit_merge_point(w_type=w_type)
+y = space.hash_w(w_item)
+x = (x ^ y) * mult
+z -= 1
+mult += 82520 + z + z
+x += 97531
+return space.wrap(intmask(x))
+
 def descr_eq(self, space, w_other):
 if not isinstance(w_other, W_AbstractTupleObject):
 return space.w_NotImplemented
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -284,7 +284,7 @@
 def loop_unrolling_heuristic(lst, size, cutoff=2):
 """ In which cases iterating over items of lst can be unrolled
 """
-return isvirtual(lst) or (isconstant(size) and size <= cutoff)
+return size == 0 or isvirtual(lst) or (isconstant(size) and size <= cutoff)
 
 class Entry(ExtRegistryEntry):
 _about_ = hint
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy look-inside-tuple-hash: close to be merged branch

2016-02-23 Thread fijal
Author: fijal
Branch: look-inside-tuple-hash
Changeset: r82455:6b597b2e2fae
Date: 2016-02-23 18:19 +0100
http://bitbucket.org/pypy/pypy/changeset/6b597b2e2fae/

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 cpyext-ext: Manually expand obscure macro

2016-02-23 Thread rlamy
Author: Ronan Lamy 
Branch: cpyext-ext
Changeset: r82454:58459ae8908d
Date: 2016-02-23 18:17 +0100
http://bitbucket.org/pypy/pypy/changeset/58459ae8908d/

Log:Manually expand obscure macro

diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c
--- a/pypy/module/cpyext/test/foo.c
+++ b/pypy/module/cpyext/test/foo.c
@@ -182,7 +182,7 @@
 {"float_member", T_FLOAT, offsetof(fooobject, foo_float), 0, NULL},
 {"double_member", T_DOUBLE, offsetof(fooobject, foo_double), 0, NULL},
 {"longlong_member", T_LONGLONG, offsetof(fooobject, foo_longlong), 0, 
NULL},
-{"ulonglong_member", T_ULONGLONG, offsetof(fooobject, foo_ulonglong), 0, 
NULL},  
+{"ulonglong_member", T_ULONGLONG, offsetof(fooobject, foo_ulonglong), 0, 
NULL},
 {"ssizet_member", T_PYSSIZET, offsetof(fooobject, foo_ssizet), 0, NULL},
 {NULL}  /* Sentinel */
 };
@@ -450,7 +450,7 @@
 if ((foop = newfooobject()) == NULL) {
 return NULL;
 }
-
+
 return (PyObject *)foop;
 }
 
@@ -666,7 +666,7 @@
 PyMethodDescr_TypePtr == PyGetSetDescr_TypePtr ||
 PyMemberDescr_TypePtr == PyGetSetDescr_TypePtr)
 {
-PyErr_Format(PyExc_RuntimeError, 
+PyErr_Format(PyExc_RuntimeError,
 "at least two of the 'Py{Method,Member,GetSet}Descr_Type's are the 
same\n"
 "(in cmp_docstring %s %d)", __FILE__, __LINE__);
 return NULL;
@@ -695,7 +695,20 @@
 _CMPDOC(CFunction, new->m_ml->ml_doc, new->m_ml->ml_name);
 }
 else if (_TESTDOC1(Type)) {
-_CMPDOC(Type, new->tp_doc, new->tp_name);
+PyTypeObject *new = (PyTypeObject *)obj;
+if (!(new->tp_doc)) {
+PyErr_Format(PyExc_RuntimeError, "Type '%s' %s", new->tp_name, 
msg);
+return NULL;
+}
+else {
+if (strcmp(new->tp_doc, docstr) != 0)
+{
+PyErr_Format(PyExc_RuntimeError,
+ "%s's docstring '%s' is not '%s'",
+ new->tp_name, new->tp_doc, docstr);
+return NULL;
+}
+}
 }
 else if (_TESTDOC2(MemberDescr)) {
 _CMPDOC(MemberDescr, new->d_member->doc, new->d_member->name);
@@ -718,13 +731,13 @@
 
 attr_as_str = PyString_AS_STRING(doc_attr);
 if (strcmp(attr_as_str, docstr) != 0)
-{   
-PyErr_Format(PyExc_RuntimeError,
- "objects's docstring '%s' is not '%s'", 
- attr_as_str, docstr);   
+{
+PyErr_Format(PyExc_RuntimeError,
+ "objects's docstring '%s' is not '%s'",
+ attr_as_str, docstr);
 Py_XDECREF(doc_attr);
-return NULL;
-}   
+return NULL;
+}
 Py_XDECREF(doc_attr);
 Py_RETURN_NONE;
 }
@@ -782,7 +795,7 @@
 return;
 if (PyType_Ready() < 0)
 return;
-
+
 SimplePropertyType.tp_new = PyType_GenericNew;
 InitErrType.tp_new = PyType_GenericNew;
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy.org pypy3-update: Backed out changeset ab7abb3e75bb

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: pypy3-update
Changeset: r709:3041468d1ea7
Date: 2016-02-23 18:04 +0100
http://bitbucket.org/pypy/pypy.org/changeset/3041468d1ea7/

Log:Backed out changeset ab7abb3e75bb

diff --git a/don1.html b/don1.html
--- a/don1.html
+++ b/don1.html
@@ -15,7 +15,7 @@
 
 

-   $62926 of $105000 (59.9%)
+   $62907 of $105000 (59.9%)


 
@@ -23,7 +23,7 @@
   
   This donation goes towards supporting Python 3 in 
PyPy.
   Current status:
-we have $8085 left
+we have $8067 left
   in the account. Read proposal
   
   
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy.org extradoc: update the values

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r708:944dcc74ad0a
Date: 2016-02-23 18:02 +0100
http://bitbucket.org/pypy/pypy.org/changeset/944dcc74ad0a/

Log:update the values

diff --git a/don1.html b/don1.html
--- a/don1.html
+++ b/don1.html
@@ -15,7 +15,7 @@
 
 

-   $62907 of $105000 (59.9%)
+   $62926 of $105000 (59.9%)


 
@@ -23,7 +23,7 @@
   
   This donation goes towards supporting Python 3 in 
PyPy.
   Current status:
-we have $8067 left
+we have $8085 left
   in the account. Read proposal
   
   
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: (fijal, cfbolz): make it possible to insert enter_portal_frame and

2016-02-23 Thread cfbolz
Author: Carl Friedrich Bolz 
Branch: 
Changeset: r82453:97c9937d38ad
Date: 2016-02-23 18:00 +0100
http://bitbucket.org/pypy/pypy/changeset/97c9937d38ad/

Log:(fijal, cfbolz): make it possible to insert enter_portal_frame and
leave_portal_frame explicitly, for the weird interpreters that need
that.

diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -2042,6 +2042,11 @@
 self.vable_flags[op.args[0]] = op.args[2].value
 return []
 
+def rewrite_op_jit_enter_portal_frame(self, op):
+return [op]
+def rewrite_op_jit_leave_portal_frame(self, op):
+return [op]
+
 # -
 # ll_math.sqrt_nonneg()
 
diff --git a/rpython/jit/metainterp/blackhole.py 
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -944,6 +944,14 @@
 pass
 
 @arguments("i")
+def bhimpl_jit_enter_portal_frame(x):
+pass
+
+@arguments()
+def bhimpl_jit_leave_portal_frame():
+pass
+
+@arguments("i")
 def bhimpl_int_assert_green(x):
 pass
 @arguments("r")
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
@@ -1358,6 +1358,17 @@
 self.metainterp.attach_debug_info(op)
 
 @arguments("box")
+def opimpl_jit_enter_portal_frame(self, uniqueidbox):
+unique_id = uniqueidbox.getint()
+jd_no = self.metainterp.jitdriver_sd.mainjitcode.index # fish
+self.metainterp.enter_portal_frame(jd_no, unique_id)
+
+@arguments()
+def opimpl_jit_leave_portal_frame(self):
+jd_no = self.metainterp.jitdriver_sd.mainjitcode.index # fish
+self.metainterp.leave_portal_frame(jd_no)
+
+@arguments("box")
 def _opimpl_assert_green(self, box):
 if not isinstance(box, Const):
 msg = "assert_green failed at %s:%d" % (
diff --git a/rpython/jit/metainterp/test/test_jitdriver.py 
b/rpython/jit/metainterp/test/test_jitdriver.py
--- a/rpython/jit/metainterp/test/test_jitdriver.py
+++ b/rpython/jit/metainterp/test/test_jitdriver.py
@@ -213,6 +213,21 @@
 if op.getopname() == 'enter_portal_frame':
 assert op.getarg(0).getint() == 0
 assert op.getarg(1).getint() == 1
-
+
+def test_manual_leave_enter_portal_frame(self):
+from rpython.rlib import jit
+driver = JitDriver(greens=[], reds='auto', is_recursive=True)
+
+def f(arg):
+i = 0
+while i < 100:
+driver.jit_merge_point()
+jit.enter_portal_frame(42)
+jit.leave_portal_frame()
+i += 1
+
+self.meta_interp(f, [0])
+self.check_resops(enter_portal_frame=1, leave_portal_frame=1)
+
 class TestLLtype(MultipleJitDriversTests, LLJitMixin):
 pass
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1168,6 +1168,24 @@
 hop.exception_is_here()
 return hop.genop('jit_conditional_call', args_v)
 
+def enter_portal_frame(unique_id):
+"""call this when starting to interpret a function. calling this is not
+necessary for almost all interpreters. The only exception is stackless
+interpreters where the portal never calls itself.
+"""
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem.lloperation import llop
+llop.jit_enter_portal_frame(lltype.Void, unique_id)
+
+def leave_portal_frame():
+"""call this after the end of executing a function. calling this is not
+necessary for almost all interpreters. The only exception is stackless
+interpreters where the portal never calls itself.
+"""
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem.lloperation import llop
+llop.jit_leave_portal_frame(lltype.Void)
+
 class Counters(object):
 counters="""
 TRACING
diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py
--- a/rpython/rlib/test/test_jit.py
+++ b/rpython/rlib/test/test_jit.py
@@ -4,7 +4,8 @@
 from rpython.annotator.model import UnionError
 from rpython.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote,
 JitHintError, oopspec, isconstant, conditional_call,
-elidable, unroll_safe, dont_look_inside)
+elidable, unroll_safe, dont_look_inside,
+enter_portal_frame, leave_portal_frame)
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.rtyper.lltypesystem import lltype
@@ -300,3 +301,11 @@
 mix = MixLevelHelperAnnotator(t.rtyper)
 mix.getgraph(later, [annmodel.s_Bool], annmodel.s_None)
 mix.finish()
+
+def 

[pypy-commit] pypy.org pypy3-update: update the values

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: pypy3-update
Changeset: r707:ab7abb3e75bb
Date: 2016-02-23 17:57 +0100
http://bitbucket.org/pypy/pypy.org/changeset/ab7abb3e75bb/

Log:update the values

diff --git a/don1.html b/don1.html
--- a/don1.html
+++ b/don1.html
@@ -15,7 +15,7 @@
 
 

-   $62907 of $105000 (59.9%)
+   $62926 of $105000 (59.9%)


 
@@ -23,7 +23,7 @@
   
   This donation goes towards supporting Python 3 in 
PyPy.
   Current status:
-we have $8067 left
+we have $8085 left
   in the account. Read proposal
   
   
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (remi, plan_rich) refactored the register manager to use the LiveRanges class

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82451:848d331e295a
Date: 2016-02-23 17:22 +0100
http://bitbucket.org/pypy/pypy/changeset/848d331e295a/

Log:(remi, plan_rich) refactored the register manager to use the
LiveRanges class

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -276,10 +276,10 @@
 save_around_call_regs = []
 frame_reg = None
 
-def __init__(self, longevity, frame_manager=None, assembler=None):
+def __init__(self, live_ranges, frame_manager=None, assembler=None):
 self.free_regs = self.all_regs[:]
 self.free_regs.reverse()
-self.longevity = longevity
+self.live_ranges = live_ranges
 self.temp_boxes = []
 if not we_are_translated():
 self.reg_bindings = OrderedDict()
@@ -293,12 +293,12 @@
 def is_still_alive(self, v):
 # Check if 'v' is alive at the current position.
 # Return False if the last usage is strictly before.
-return self.longevity[v][1] >= self.position
+return self.live_ranges.last_use(v) >= self.position
 
 def stays_alive(self, v):
 # Check if 'v' stays alive after the current position.
 # Return False if the last usage is before or at position.
-return self.longevity[v][1] > self.position
+return self.live_ranges.last_use(v) > self.position
 
 def next_instruction(self, incr=1):
 self.position += incr
@@ -315,7 +315,7 @@
 self._check_type(v)
 if isinstance(v, Const):
 return
-if v not in self.longevity or self.longevity[v][1] <= self.position:
+if not self.live_ranges.exists(v) or self.live_ranges.last_use(v) <= 
self.position:
 if v in self.reg_bindings:
 self.free_regs.append(self.reg_bindings[v])
 del self.reg_bindings[v]
@@ -347,9 +347,9 @@
 else:
 assert len(self.reg_bindings) + len(self.free_regs) == 
len(self.all_regs)
 assert len(self.temp_boxes) == 0
-if self.longevity:
+if self.live_ranges.longevity:
 for v in self.reg_bindings:
-assert self.longevity[v][1] > self.position
+assert self.live_ranges.last_use(v) > self.position
 
 def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
 """ Try to allocate a register, if we have one free.
@@ -425,7 +425,7 @@
 continue
 if need_lower_byte and reg in self.no_lower_byte_regs:
 continue
-max_age = self.longevity[next][1]
+max_age = self.live_ranges.last_use(next)
 if cur_max_age < max_age:
 cur_max_age = max_age
 candidate = next
@@ -444,7 +444,7 @@
 """
 self._check_type(v)
 if isinstance(v, TempVar):
-self.longevity[v] = (self.position, self.position)
+self.live_ranges.new_live_range(v, self.position, self.position)
 loc = self.try_allocate_reg(v, selected_reg,
 need_lower_byte=need_lower_byte)
 if loc:
@@ -554,7 +554,7 @@
 loc = self.force_allocate_reg(v, forbidden_vars)
 self.assembler.regalloc_mov(prev_loc, loc)
 assert v in self.reg_bindings
-if self.longevity[v][1] > self.position:
+if self.live_ranges.last_use(v) > self.position:
 # we need to find a new place for variable v and
 # store result in the same place
 loc = self.reg_bindings[v]
@@ -583,7 +583,7 @@
 1 (save all), or 2 (save default+PTRs).
 """
 for v, reg in self.reg_bindings.items():
-if v not in force_store and self.longevity[v][1] <= self.position:
+if v not in force_store and self.live_ranges.last_use(v) <= 
self.position:
 # variable dies
 del self.reg_bindings[v]
 self.free_regs.append(reg)
@@ -677,6 +677,15 @@
 self.last_real_usage = last_real_usage
 self.dist_to_next_call = dist_to_next_call
 
+def exists(self, var):
+ return var in self.longevity
+
+def last_use(self, var):
+ return self.longevity[var][1]
+
+def new_live_range(self, var, start, end):
+ self.longevity[var] = (start, end)
+
 def compute_var_live_ranges(inputargs, operations):
 # compute a dictionary that maps variables to index in
 # operations that is a "last-time-seen"
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py 
b/rpython/jit/backend/llsupport/test/test_regalloc.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc.py
@@ -2,6 +2,7 @@
 from rpython.jit.metainterp.history import 

[pypy-commit] pypy fix-longevity: (plan_rich,remi) fix test

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82452:17b7cbcf32e2
Date: 2016-02-23 17:28 +0100
http://bitbucket.org/pypy/pypy/changeset/17b7cbcf32e2/

Log:(plan_rich,remi) fix test

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -99,7 +99,7 @@
 def __init__(self, trace, caller_saved, callee_saved, binding, tt):
 self.trace = trace
 self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
-self.initial_binding = { var: reg for var, reg in zip(trace.inputargs, 
binding) }
+self.initial_binding = {var: reg for var, reg in zip(trace.inputargs, 
binding) }
 tt._x86_arglocs = binding
 
 def run_allocation(self, free_regs=None):
@@ -125,7 +125,8 @@
 # instead of having all machine registers, we want only to provide some
 fr = self.regalloc.free_regs
 if free_regs is None:
-self.regalloc.rm.free_regs = [reg for reg in fr if reg not in 
binding]
+self.regalloc.rm.free_regs = [reg for reg in fr
+  if reg not in 
self.initial_binding.values()]
 else:
 self.regalloc.rm.free_regs = free_regs
 self.regalloc.rm.all_regs = self.regalloc.all_regs
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy look-inside-tuple-hash: look inside tuple hash

2016-02-23 Thread fijal
Author: fijal
Branch: look-inside-tuple-hash
Changeset: r82450:7935d5732094
Date: 2016-02-23 17:21 +0100
http://bitbucket.org/pypy/pypy/changeset/7935d5732094/

Log:look inside tuple hash

diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -30,6 +30,11 @@
 contains_jmp = jit.JitDriver(greens = ['tp'], reds = 'auto',
  name = 'tuple.contains')
 
+hash_driver = jit.JitDriver(
+name='tuple.hash',
+greens=['w_type'],
+reds='auto')
+
 class W_AbstractTupleObject(W_Root):
 __slots__ = ()
 
@@ -262,8 +267,14 @@
 def length(self):
 return len(self.wrappeditems)
 
-@jit.look_inside_iff(lambda self, _1: _unroll_condition(self))
 def descr_hash(self, space):
+if _unroll_condition(self):
+return self._descr_hash_unroll(space)
+else:
+return self._descr_hash_jitdriver(space)
+
+@jit.unroll_safe
+def _descr_hash_unroll(self, space):
 mult = 103
 x = 0x345678
 z = len(self.wrappeditems)
@@ -275,6 +286,20 @@
 x += 97531
 return space.wrap(intmask(x))
 
+def _descr_hash_jitdriver(self, space):
+mult = 103
+x = 0x345678
+z = len(self.wrappeditems)
+w_type = space.type(self.wrappeditems[0])
+for w_item in self.wrappeditems:
+hash_driver.jit_merge_point(w_type=w_type)
+y = space.hash_w(w_item)
+x = (x ^ y) * mult
+z -= 1
+mult += 82520 + z + z
+x += 97531
+return space.wrap(intmask(x))
+
 def descr_eq(self, space, w_other):
 if not isinstance(w_other, W_AbstractTupleObject):
 return space.w_NotImplemented
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -284,7 +284,7 @@
 def loop_unrolling_heuristic(lst, size, cutoff=2):
 """ In which cases iterating over items of lst can be unrolled
 """
-return isvirtual(lst) or (isconstant(size) and size <= cutoff)
+return size == 0 or isvirtual(lst) or (isconstant(size) and size <= cutoff)
 
 class Entry(ExtRegistryEntry):
 _about_ = hint
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (remi, plan_rich) a new test to check that liveranges containing calls will prefer callee_saved registers

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82449:e1c902c90c70
Date: 2016-02-23 16:55 +0100
http://bitbucket.org/pypy/pypy/changeset/e1c902c90c70/

Log:(remi, plan_rich) a new test to check that liveranges containing
calls will prefer callee_saved registers

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -23,6 +23,11 @@
 
 CPU = getcpuclass()
 
+def get_param(i):
+# x86 specific!!
+ABI_PARAMS_REGISTERS = [edi, esi, edx, ecx, r8, r9]
+return ABI_PARAMS_REGISTERS[i]
+
 def parse_loop(text, namespace={}):
 ops = parse(text, namespace=namespace)
 tt = None
@@ -95,31 +100,49 @@
 self.trace = trace
 self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
 self.initial_binding = { var: reg for var, reg in zip(trace.inputargs, 
binding) }
+tt._x86_arglocs = binding
+
+def run_allocation(self, free_regs=None):
+inputargs = self.trace.inputargs
+operations = self.trace.operations
 looptoken = FakeLoopToken()
 gcrefs = []
-tt._x86_arglocs = binding
 
+# force naming of the variables!
 AbstractValue._repr_memo = CountingDict()
-for op in trace.operations:
+for op in operations:
 for arg in op.getarglist():
 arg.repr_short(arg._repr_memo)
-pass
 op.repr_short(op._repr_memo)
-self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
 
-for var, reg in zip(trace.inputargs, binding):
+# setup the register allocator
+self.regalloc.prepare_loop(inputargs, operations, looptoken, gcrefs)
+
+# setup the initial binding the test requires
+for var, reg in self.initial_binding.items():
 self.regalloc.rm.reg_bindings[var] = reg
+
+# instead of having all machine registers, we want only to provide some
 fr = self.regalloc.free_regs
-self.regalloc.rm.free_regs = [reg for reg in fr if reg not in binding]
-
+if free_regs is None:
+self.regalloc.rm.free_regs = [reg for reg in fr if reg not in 
binding]
+else:
+self.regalloc.rm.free_regs = free_regs
 self.regalloc.rm.all_regs = self.regalloc.all_regs
 self.regalloc.rm.save_around_call_regs = self.regalloc.caller_saved
 
-self.regalloc.walk_operations(trace.inputargs, trace.operations)
+# invoke the allocator!
+self.regalloc.walk_operations(inputargs, operations)
 
 def initial_register(self, var):
 return self.initial_binding.get(var, None)
 
+def is_caller_saved(self, var):
+return self.initial_register(var) in self.regalloc.caller_saved
+
+def is_callee_saved(self, var):
+return self.initial_register(var) in self.regalloc.callee_saved
+
 def move_count(self):
 return len(self.regalloc.assembler.moves)
 
@@ -153,11 +176,13 @@
 i3 = int_add(i2,i1)
 jump(p0,i2)
 """)
+i2 = ops.operations[0]
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-i2 = trace_alloc.initial_register('i2')
+trace_alloc.run_allocation()
+i2 = trace_alloc.initial_register(i2)
 assert i2 == edx
 
-def test_2allocate_register_into_jump_register2(self):
+def test_single_move(self):
 tt, ops = parse_loop("""
 [p0,i0]
 i1 = int_add(i0,i0)
@@ -165,27 +190,29 @@
 guard_true(i2) []
 jump(p0,i1)
 """)
-i1 = ops.operations[0]
-i2 = ops.operations[1]
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-assert trace_alloc.initial_register(i1) == edx
-assert trace_alloc.initial_register(i2) != edx
+trace_alloc.run_allocation()
 assert trace_alloc.move_count() == 1
 
-def test_call_allocate_first_param_to_callee(self):
+def test_prefer_callee_saved_register(self):
 tt, ops = parse_loop("""
 [p0,i0]
 i1 = int_add(i0,i0)
-i2 = int_add(i0,i1)
+i2 = int_sub(i0,i1)
 call_n(p0, i1, descr=calldescr)
-guard_true(i2) []
-jump(p0,i1)
+i3 = int_mul(i2,i0)
+jump(p0,i2)
 """, namespace=self.namespace)
 i1 = ops.operations[0]
 i2 = ops.operations[1]
-trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-assert trace_alloc.initial_register(i1) == edx
-assert trace_alloc.initial_register(i2) != edx
+trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9, r10], [eax, 
r10], tt)
+trace_alloc.run_allocation([r8,r9,edx])
+# we force the allocation to 

[pypy-commit] pypy fix-longevity: (plan_rich, remi) add test for call distance calculation

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82448:fa5e185b9757
Date: 2016-02-23 16:50 +0100
http://bitbucket.org/pypy/pypy/changeset/fa5e185b9757/

Log:(plan_rich,remi) add test for call distance calculation

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
@@ -7,7 +7,8 @@
  TargetToken
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.backend.detect_cpu import getcpuclass
-from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op
+from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op,\
+compute_var_live_ranges
 from rpython.jit.tool.oparser import parse
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rtyper.annlowlevel import llhelper
@@ -155,6 +156,40 @@
 return self.cpu.get_latest_descr(self.deadframe)
 
 class TestRegallocSimple(BaseTestRegalloc):
+def test_compute_live_ranges(self):
+ops = '''
+[i0]
+label(i0, descr=targettoken)
+i1 = int_add(i0, 1)
+i2 = int_lt(i1, 20)
+guard_true(i2) [i1]
+jump(i1, descr=targettoken)
+'''
+loop = self.parse(ops)
+lrs = compute_var_live_ranges(loop.inputargs, loop.operations)
+assert lrs.longevity[loop.operations[1]] == (1, 4)
+assert lrs.longevity[loop.operations[2]] == (2, 3)
+assert lrs.last_real_usage[loop.operations[1]] == 2
+assert lrs.last_real_usage[loop.operations[2]] == 3
+assert all([i < 0 for i in lrs.dist_to_next_call])
+
+def test_compute_call_distances(self):
+ops = '''
+[i0]
+label(i0, descr=targettoken)
+i1 = int_add(i0, 1)
+i2 = int_lt(i1, 20)
+call_n(ConstClass(raising_fptr), i0, descr=raising_calldescr)
+guard_true(i2) [i1]
+call_n(ConstClass(raising_fptr), i0, descr=raising_calldescr)
+guard_true(i2) [i1]
+jump(i1, descr=targettoken)
+'''
+loop = self.parse(ops)
+lrs = compute_var_live_ranges(loop.inputargs, loop.operations)
+assert lrs.dist_to_next_call == [3, 2, 1, 0, 1, 0, -7, -8]
+
+
 def test_simple_loop(self):
 ops = '''
 [i0]
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: fix for renames

2016-02-23 Thread mattip
Author: mattip 
Branch: 
Changeset: r82446:1df21a900a84
Date: 2016-02-23 15:06 +0100
http://bitbucket.org/pypy/pypy/changeset/1df21a900a84/

Log:fix for renames

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -34,7 +34,7 @@
 import pypy.module.cpyext.pyerrors
 import pypy.module.cpyext.typeobject
 import pypy.module.cpyext.object
-import pypy.module.cpyext.stringobject
+import pypy.module.cpyext.bytesobject
 import pypy.module.cpyext.tupleobject
 import pypy.module.cpyext.setobject
 import pypy.module.cpyext.dictobject
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -303,7 +303,7 @@
 def from_ref(space, ref):
 """
 Finds the interpreter object corresponding to the given reference.  If the
-object is not yet realized (see stringobject.py), creates it.
+object is not yet realized (see bytesobject.py), creates it.
 """
 assert lltype.typeOf(ref) == PyObject
 if not ref:
diff --git a/pypy/module/cpyext/structmember.py 
b/pypy/module/cpyext/structmember.py
--- a/pypy/module/cpyext/structmember.py
+++ b/pypy/module/cpyext/structmember.py
@@ -6,7 +6,7 @@
 from pypy.module.cpyext.intobject import PyInt_AsLong, PyInt_AsUnsignedLong
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, from_ref, make_ref
-from pypy.module.cpyext.stringobject import (
+from pypy.module.cpyext.bytesobject import (
 PyString_FromString, PyString_FromStringAndSize)
 from pypy.module.cpyext.floatobject import PyFloat_AsDouble
 from pypy.module.cpyext.longobject import (
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.stringobject import new_empty_str, PyStringObject
+from pypy.module.cpyext.bytesobject import new_empty_str, PyStringObject
 from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP
 from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
 
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -337,7 +337,7 @@
 @cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
  header=None, error=-1)
 def str_getreadbuffer(space, w_str, segment, ref):
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 if segment != 0:
 raise OperationError(space.w_SystemError, space.wrap
  ("accessing non-existent string segment"))
@@ -350,7 +350,7 @@
 @cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
  header=None, error=-1)
 def str_getcharbuffer(space, w_str, segment, ref):
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 if segment != 0:
 raise OperationError(space.w_SystemError, space.wrap
  ("accessing non-existent string segment"))
@@ -460,7 +460,7 @@
 w_typename = space.getattr(w_type, space.wrap('__name__'))
 heaptype = rffi.cast(PyHeapTypeObject, pto)
 heaptype.c_ht_name = make_ref(space, w_typename)
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
 else:
 pto.c_tp_name = rffi.str2charp(w_type.name)
diff --git a/pypy/module/cpyext/unicodeobject.py 
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -9,7 +9,7 @@
 from pypy.module.cpyext.pyobject import (
 PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
 make_typedescr, get_typedescr)
-from pypy.module.cpyext.stringobject import PyString_Check
+from pypy.module.cpyext.bytesobject import PyString_Check
 from pypy.module.sys.interp_encoding import setdefaultencoding
 from pypy.module._codecs.interp_codecs import CodecState
 from pypy.objspace.std import unicodeobject
@@ -17,7 +17,7 @@
 from rpython.tool.sourcetools import func_renamer
 import sys
 
-## See comment in stringobject.py.
+## See comment in bytesobject.py.
 
 PyUnicodeObjectStruct = lltype.ForwardReference()
 PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
___

[pypy-commit] pypy default: rename stringobject.py to bytesobject.py

2016-02-23 Thread mattip
Author: mattip 
Branch: 
Changeset: r82445:e2a7fc01c7db
Date: 2016-02-23 15:00 +0100
http://bitbucket.org/pypy/pypy/changeset/e2a7fc01c7db/

Log:rename stringobject.py to bytesobject.py

diff --git a/pypy/module/cpyext/stringobject.py 
b/pypy/module/cpyext/bytesobject.py
rename from pypy/module/cpyext/stringobject.py
rename to pypy/module/cpyext/bytesobject.py
diff --git a/pypy/module/cpyext/test/test_stringobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
rename from pypy/module/cpyext/test/test_stringobject.py
rename to pypy/module/cpyext/test/test_bytesobject.py
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: merge heads

2016-02-23 Thread mattip
Author: mattip 
Branch: 
Changeset: r82447:904c371acd44
Date: 2016-02-23 16:34 +0100
http://bitbucket.org/pypy/pypy/changeset/904c371acd44/

Log:merge heads

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -34,7 +34,7 @@
 import pypy.module.cpyext.pyerrors
 import pypy.module.cpyext.typeobject
 import pypy.module.cpyext.object
-import pypy.module.cpyext.stringobject
+import pypy.module.cpyext.bytesobject
 import pypy.module.cpyext.tupleobject
 import pypy.module.cpyext.setobject
 import pypy.module.cpyext.dictobject
diff --git a/pypy/module/cpyext/stringobject.py 
b/pypy/module/cpyext/bytesobject.py
rename from pypy/module/cpyext/stringobject.py
rename to pypy/module/cpyext/bytesobject.py
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -191,7 +191,7 @@
 def from_ref(space, ref):
 """
 Finds the interpreter object corresponding to the given reference.  If the
-object is not yet realized (see stringobject.py), creates it.
+object is not yet realized (see bytesobject.py), creates it.
 """
 assert is_pyobj(ref)
 if not ref:
diff --git a/pypy/module/cpyext/structmember.py 
b/pypy/module/cpyext/structmember.py
--- a/pypy/module/cpyext/structmember.py
+++ b/pypy/module/cpyext/structmember.py
@@ -6,7 +6,7 @@
 from pypy.module.cpyext.intobject import PyInt_AsLong, PyInt_AsUnsignedLong
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, from_ref, make_ref
-from pypy.module.cpyext.stringobject import (
+from pypy.module.cpyext.bytesobject import (
 PyString_FromString, PyString_FromStringAndSize)
 from pypy.module.cpyext.floatobject import PyFloat_AsDouble
 from pypy.module.cpyext.longobject import (
diff --git a/pypy/module/cpyext/test/test_stringobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
rename from pypy/module/cpyext/test/test_stringobject.py
rename to pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.stringobject import new_empty_str, PyStringObject
+from pypy.module.cpyext.bytesobject import new_empty_str, PyStringObject
 from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP
 from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
 
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -340,7 +340,7 @@
 @cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
  header=None, error=-1)
 def str_getreadbuffer(space, w_str, segment, ref):
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 if segment != 0:
 raise OperationError(space.w_SystemError, space.wrap
  ("accessing non-existent string segment"))
@@ -353,7 +353,7 @@
 @cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
  header=None, error=-1)
 def str_getcharbuffer(space, w_str, segment, ref):
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 if segment != 0:
 raise OperationError(space.w_SystemError, space.wrap
  ("accessing non-existent string segment"))
@@ -463,7 +463,7 @@
 w_typename = space.getattr(w_type, space.wrap('__name__'))
 heaptype = rffi.cast(PyHeapTypeObject, pto)
 heaptype.c_ht_name = make_ref(space, w_typename)
-from pypy.module.cpyext.stringobject import PyString_AsString
+from pypy.module.cpyext.bytesobject import PyString_AsString
 pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
 else:
 pto.c_tp_name = rffi.str2charp(w_type.name)
diff --git a/pypy/module/cpyext/unicodeobject.py 
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -9,7 +9,7 @@
 from pypy.module.cpyext.pyobject import (
 PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
 make_typedescr, get_typedescr)
-from pypy.module.cpyext.stringobject import PyString_Check
+from pypy.module.cpyext.bytesobject import PyString_Check
 from pypy.module.sys.interp_encoding import setdefaultencoding
 from pypy.module._codecs.interp_codecs import CodecState
 from pypy.objspace.std import unicodeobject
@@ -17,7 +17,7 @@
 from 

[pypy-commit] pypy fix-longevity: (plan_rich, remi) start implementing heuristic for choosing callee vs caller registers

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82444:b5c6184fc5e6
Date: 2016-02-23 16:10 +0100
http://bitbucket.org/pypy/pypy/changeset/b5c6184fc5e6/

Log:(plan_rich,remi) start implementing heuristic for choosing callee vs
caller registers

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -671,16 +671,24 @@
 return [self.loc(op.getarg(0))]
 
 
-def compute_vars_longevity(inputargs, operations):
+class LiveRanges(object):
+def __init__(self, longevity, last_real_usage, dist_to_next_call):
+self.longevity = longevity
+self.last_real_usage = last_real_usage
+self.dist_to_next_call = dist_to_next_call
+
+def compute_var_live_ranges(inputargs, operations):
 # compute a dictionary that maps variables to index in
 # operations that is a "last-time-seen"
 
-# returns a pair longevity/useful. Non-useful variables are ones that
+# returns a Longevity object with longevity/useful. Non-useful variables 
are ones that
 # never appear in the assembler or it does not matter if they appear on
 # stack or in registers. Main example is loop arguments that go
 # only to guard operations or to jump or to finish
 last_used = {}
 last_real_usage = {}
+dist_to_next_call = [0] * len(operations)
+last_call_pos = -1
 for i in range(len(operations)-1, -1, -1):
 op = operations[i]
 if op.type != 'v':
@@ -703,6 +711,9 @@
 assert not isinstance(arg, Const)
 if arg not in last_used:
 last_used[arg] = i
+if op.is_call():
+last_call_pos = i
+dist_to_next_call[i] = last_call_pos - i
 #
 longevity = {}
 for i, arg in enumerate(operations):
@@ -729,8 +740,8 @@
 if not isinstance(arg, Const):
 assert arg in produced
 produced[op] = None
-
-return longevity, last_real_usage
+
+return LiveRanges(longevity, last_real_usage, dist_to_next_call)
 
 def is_comparison_or_ovf_op(opnum):
 from rpython.jit.metainterp.resoperation import opclasses
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -141,8 +141,9 @@
 FPTR = lltype.Ptr(lltype.FuncType([rffi.UINT], rffi.UINT))
 func_ptr = llhelper(FPTR, x)
 calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, 
EffectInfo.MOST_GENERAL)
+targettoken = TargetToken()
 
-ns = {'calldescr': calldescr}
+ns = {'calldescr': calldescr, 'targettoken':targettoken}
 self.namespace = ns
 
 def test_allocate_register_into_jump_register(self):
@@ -187,3 +188,22 @@
 assert trace_alloc.initial_register(i2) != edx
 assert trace_alloc.move_count() == 1
 
+def test_call_allocate_first_param_to_callee2(self):
+tt, ops = parse_loop("""
+[p0,i0]
+
+label(p0,i0,descr=targettoken)
+
+i1 = int_add(i0,i0)
+i2 = int_add(i0,i1)
+call_n(p0, i1, descr=calldescr)
+guard_true(i2) []
+
+jump(p0,i1,descr=targettoken)
+""", namespace=self.namespace)
+i1 = ops.operations[0]
+i2 = ops.operations[1]
+trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
+assert trace_alloc.initial_register(i1) == edx
+assert trace_alloc.initial_register(i2) != edx
+assert trace_alloc.move_count() == 1
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
@@ -7,7 +7,7 @@
 from rpython.jit.backend.llsupport.descr import CallDescr, unpack_arraydescr
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.regalloc import (FrameManager, BaseRegalloc,
- RegisterManager, TempVar, compute_vars_longevity, is_comparison_or_ovf_op,
+ RegisterManager, TempVar, compute_var_live_ranges, 
is_comparison_or_ovf_op,
  valid_addressing_size)
 from rpython.jit.backend.x86 import rx86
 from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32,
@@ -164,10 +164,10 @@
 operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
allgcrefs)
 # compute longevity of variables
-longevity, last_real_usage = compute_vars_longevity(
-inputargs, operations)
-self.longevity = longevity
-self.last_real_usage = last_real_usage
+live_ranges = 

[pypy-commit] pypy cpyext-ext: Fix for running -A cpyext tests

2016-02-23 Thread rlamy
Author: Ronan Lamy 
Branch: cpyext-ext
Changeset: r82443:cf846c1b0068
Date: 2016-02-23 16:07 +0100
http://bitbucket.org/pypy/pypy/changeset/cf846c1b0068/

Log:Fix for running -A cpyext tests

diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -285,7 +285,7 @@
 return space.wrap(pydname)
 
 @gateway.unwrap_spec(name=str, init='str_or_None', body=str,
- load_it=bool, filename='str_or_None', 
+ load_it=bool, filename='str_or_None',
  PY_SSIZE_T_CLEAN=bool)
 def import_module(space, name, init=None, body='', load_it=True,
   filename=None, w_include_dirs=None,
@@ -307,7 +307,7 @@
 code = """
 %(PY_SSIZE_T_CLEAN)s
 #include 
-/* fix for cpython 2.7 Python.h if running tests with -A 
+/* fix for cpython 2.7 Python.h if running tests with -A
since pypy compiles with -fvisibility-hidden */
 #undef PyMODINIT_FUNC
 #define PyMODINIT_FUNC RPY_EXPORTED void
@@ -433,9 +433,8 @@
 self.w_reimport_module = wrap(interp2app(reimport_module))
 self.w_import_extension = wrap(interp2app(import_extension))
 self.w_record_imported_module = 
wrap(interp2app(record_imported_module))
-self.w_here = self.space.wrap(
-str(py.path.local(pypydir)) + '/module/cpyext/test/')
-self.w_debug_collect = self.space.wrap(interp2app(debug_collect))
+self.w_here = wrap(str(py.path.local(pypydir)) + 
'/module/cpyext/test/')
+self.w_debug_collect = wrap(interp2app(debug_collect))
 
 # create the file lock before we count allocations
 self.space.call_method(self.space.sys.get("stdout"), "flush")
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-ext: fix test: types which have the same size as PyObject should not cause instance layout conflicts

2016-02-23 Thread rlamy
Author: Ronan Lamy 
Branch: cpyext-ext
Changeset: r82442:7ee3179525f3
Date: 2016-02-23 15:33 +0100
http://bitbucket.org/pypy/pypy/changeset/7ee3179525f3/

Log:fix test: types which have the same size as PyObject should not
cause instance layout conflicts

diff --git a/pypy/module/cpyext/test/test_typeobject.py 
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -396,7 +396,7 @@
 which should have a different tp_getattro/tp_setattro
 than its tp_base, which is 'object'.
   */
-  
+
  if (!args->ob_type->tp_setattro)
  {
  PyErr_SetString(PyExc_ValueError, "missing tp_setattro");
@@ -719,7 +719,7 @@
 long ival;
 } IntLikeObject;
 
-static PyObject * 
+static PyObject *
 intlike_nb_add(PyObject *self, PyObject *other)
 {
 long val2, val1 = ((IntLikeObject *)(self))->ival;
@@ -782,7 +782,7 @@
 def test_app_cant_subclass_two_types(self):
 module = self.import_module(name='foo')
 try:
-class bar(module.fooType, module.Property):
+class bar(module.fooType, module.UnicodeSubtype):
 pass
 except TypeError as e:
 assert str(e) == 'instance layout conflicts in multiple 
inheritance'
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (remi, plan_rich) resolved one issue in the allocation. this avoids reloading from the frame if one variable is already in a register

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82441:efbb3a7664a1
Date: 2016-02-23 15:28 +0100
http://bitbucket.org/pypy/pypy/changeset/efbb3a7664a1/

Log:(remi, plan_rich) resolved one issue in the allocation. this avoids
reloading from the frame if one variable is already in a register

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -559,8 +559,9 @@
 # store result in the same place
 loc = self.reg_bindings[v]
 del self.reg_bindings[v]
-if self.frame_manager.get(v) is None:
+if self.frame_manager.get(v) is None or self.free_regs:
 self._move_variable_away(v, loc)
+
 self.reg_bindings[result_v] = loc
 else:
 self._reallocate_from_to(v, result_v)
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py 
b/rpython/jit/backend/llsupport/test/test_regalloc.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc.py
@@ -249,6 +249,24 @@
 loc = rm.loc(b1)
 assert isinstance(loc, FakeReg)
 loc = rm.loc(b0)
+assert isinstance(loc, FakeReg)
+assert len(asm.moves) == 2
+
+def test_force_result_in_register_reload_parameter_from_frame_later(self):
+b0, b1 = newboxes(0, 0)
+longevity = {b0: (0, 1), b1: (0, 1)}
+fm = TFrameManager()
+asm = MockAsm()
+rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+rm.free_regs = rm.free_regs[:1]
+rm.all_regs = rm.free_regs[:]
+rm.next_instruction()
+fm.loc(b0)
+rm.force_result_in_reg(b1, b0)
+rm._check_invariants()
+loc = rm.loc(b1)
+assert isinstance(loc, FakeReg)
+loc = rm.loc(b0)
 assert isinstance(loc, FakeFramePos)
 assert len(asm.moves) == 1
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-ext: obscure hack

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: cpyext-ext
Changeset: r82440:40299bc038b2
Date: 2016-02-23 15:00 +0100
http://bitbucket.org/pypy/pypy/changeset/40299bc038b2/

Log:obscure hack

diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -376,9 +376,11 @@
 convert_member_defs(space, dict_w, pto.c_tp_members, self)
 
 name = rffi.charp2str(pto.c_tp_name)
+new_layout = (pto.c_tp_basicsize > rffi.sizeof(PyObject.TO) or
+  pto.c_tp_itemsize > 0)
 
 W_TypeObject.__init__(self, space, name,
-bases_w or [space.w_object], dict_w, force_new_layout=True)
+bases_w or [space.w_object], dict_w, force_new_layout=new_layout)
 if not space.is_true(space.issubtype(self, space.w_type)):
 self.flag_cpytype = True
 self.flag_heaptype = False
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (remi, plan_rich) new test involving a call

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82439:a5af78134022
Date: 2016-02-23 14:58 +0100
http://bitbucket.org/pypy/pypy/changeset/a5af78134022/

Log:(remi, plan_rich) new test involving a call

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -6,6 +6,10 @@
 from rpython.jit.metainterp.history import TargetToken
 from rpython.jit.metainterp.resoperation import (rop, ResOperation,
 AbstractValue, CountingDict)
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.annlowlevel import llhelper
+from rpython.jit.codewriter.effectinfo import EffectInfo
 
 class FakeReg(object):
 def __init__(self, i):
@@ -19,8 +23,8 @@
 
 CPU = getcpuclass()
 
-def parse_loop(text):
-ops = parse(text)
+def parse_loop(text, namespace={}):
+ops = parse(text, namespace=namespace)
 tt = None
 tt = TargetToken(ops.operations[-1].getdescr())
 for op in ops.operations:
@@ -47,7 +51,7 @@
 self.pushes = []
 
 def regalloc_mov(self, prev_loc, loc):
-self.moves.append((prev_loc, loc))
+self.moves.append((prev_loc, loc, 'pos: ' + 
str(self.regalloc.rm.position)))
 print "mov bindings: ", self.regalloc.rm.reg_bindings
 print prev_loc, "->", loc
 def regalloc_push(self, loc):
@@ -128,6 +132,19 @@
 
 class TestRegalloc(object):
 
+def setup_method(self, name):
+cpu = CPU(None, None)
+cpu.setup_once()
+
+def x(i):
+return i
+FPTR = lltype.Ptr(lltype.FuncType([rffi.UINT], rffi.UINT))
+func_ptr = llhelper(FPTR, x)
+calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, 
EffectInfo.MOST_GENERAL)
+
+ns = {'calldescr': calldescr}
+self.namespace = ns
+
 def test_allocate_register_into_jump_register(self):
 tt, ops = parse_loop("""
 [p0,i1]
@@ -141,15 +158,32 @@
 
 def test_2allocate_register_into_jump_register2(self):
 tt, ops = parse_loop("""
-[p0,i1]
-i2 = int_add(i1,i1)
-i3 = int_add(i2,i1)
-guard_true(i3) []
-jump(p0,i2)
+[p0,i0]
+i1 = int_add(i0,i0)
+i2 = int_add(i0,i1)
+guard_true(i2) []
+jump(p0,i1)
 """)
-i2 = ops.operations[0]
-i3 = ops.operations[1]
+i1 = ops.operations[0]
+i2 = ops.operations[1]
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-assert trace_alloc.initial_register(i2) == edx
-assert trace_alloc.initial_register(i3) != edx
+assert trace_alloc.initial_register(i1) == edx
+assert trace_alloc.initial_register(i2) != edx
+assert trace_alloc.move_count() == 1
 
+def test_call_allocate_first_param_to_callee(self):
+tt, ops = parse_loop("""
+[p0,i0]
+i1 = int_add(i0,i0)
+i2 = int_add(i0,i1)
+call_n(p0, i1, descr=calldescr)
+guard_true(i2) []
+jump(p0,i1)
+""", namespace=self.namespace)
+i1 = ops.operations[0]
+i2 = ops.operations[1]
+trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
+assert trace_alloc.initial_register(i1) == edx
+assert trace_alloc.initial_register(i2) != edx
+assert trace_alloc.move_count() == 1
+
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-ext: hg merge default

2016-02-23 Thread rlamy
Author: Ronan Lamy 
Branch: cpyext-ext
Changeset: r82438:7fad651c7daf
Date: 2016-02-23 14:39 +0100
http://bitbucket.org/pypy/pypy/changeset/7fad651c7daf/

Log:hg merge default

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
@@ -128,6 +128,7 @@
 
 Fix SSL tests by importing cpython's patch
 
+
 .. branch: remove-getfield-pure
 
 Remove pure variants of ``getfield_gc_*`` operations from the JIT. Relevant
@@ -163,3 +164,10 @@
 .. branch: windows-vmprof-support
 
 vmprof should work on Windows.
+
+
+.. branch: reorder-map-attributes
+
+When creating instances and adding attributes in several different orders
+depending on some condition, the JIT would create too much code. This is now
+fixed.
\ No newline at end of file
diff --git a/pypy/module/imp/test/test_import.py 
b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -1061,12 +1061,12 @@
 py.test.skip("unresolved issues with win32 shell quoting rules")
 from pypy.interpreter.test.test_zpy import pypypath 
 extrapath = udir.ensure("pythonpath", dir=1) 
-extrapath.join("urllib.py").write("print 42\n")
+extrapath.join("sched.py").write("print 42\n")
 old = os.environ.get('PYTHONPATH', None)
 oldlang = os.environ.pop('LANG', None)
 try:
 os.environ['PYTHONPATH'] = str(extrapath)
-output = py.process.cmdexec('''"%s" "%s" -c "import urllib"''' %
+output = py.process.cmdexec('''"%s" "%s" -c "import sched"''' %
  (sys.executable, pypypath))
 assert output.strip() == '42'
 finally:
diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py 
b/pypy/module/pypyjit/test_pypy_c/test_string.py
--- a/pypy/module/pypyjit/test_pypy_c/test_string.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_string.py
@@ -28,7 +28,6 @@
 guard_true(i14, descr=...)
 guard_not_invalidated(descr=...)
 i16 = int_eq(i6, %d)
-guard_false(i16, descr=...)
 i15 = int_mod(i6, i10)
 i17 = int_rshift(i15, %d)
 i18 = int_and(i10, i17)
@@ -68,7 +67,6 @@
 guard_true(i11, descr=...)
 guard_not_invalidated(descr=...)
 i13 = int_eq(i6, %d) # value provided below
-guard_false(i13, descr=...)
 i15 = int_mod(i6, 10)
 i17 = int_rshift(i15, %d)# value provided below
 i18 = int_and(10, i17)
@@ -144,43 +142,6 @@
 jump(..., descr=...)
 """)
 
-def test_getattr_promote(self):
-def main(n):
-class A(object):
-def meth_a(self):
-return 1
-def meth_b(self):
-return 2
-a = A()
-
-l = ['a', 'b']
-s = 0
-for i in range(n):
-name = 'meth_' + l[i & 1]
-meth = getattr(a, name) # ID: getattr
-s += meth()
-return s
-
-log = self.run(main, [1000])
-assert log.result == main(1000)
-loops = log.loops_by_filename(self.filepath)
-assert len(loops) == 1
-for loop in loops:
-assert loop.match_by_id('getattr','''
-guard_not_invalidated?
-i32 = strlen(p31)
-i34 = int_add(5, i32)
-p35 = newstr(i34)
-strsetitem(p35, 0, 109)
-strsetitem(p35, 1, 101)
-strsetitem(p35, 2, 116)
-strsetitem(p35, 3, 104)
-strsetitem(p35, 4, 95)
-copystrcontent(p31, p35, 0, 5, i32)
-i49 = 
call_i(ConstClass(_ll_2_str_eq_nonnull__rpy_stringPtr_rpy_stringPtr), p35, 
ConstPtr(ptr48), descr=)
-guard_value(i49, 1, descr=...)
-''')
-
 def test_remove_duplicate_method_calls(self):
 def main(n):
 lst = []
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -1,4 +1,4 @@
-import weakref
+import weakref, sys
 
 from rpython.rlib import jit, objectmodel, debug, rerased
 from rpython.rlib.rarithmetic import intmask, r_uint
@@ -12,6 +12,11 @@
 from pypy.objspace.std.typeobject import MutableCell
 
 
+erase_item, unerase_item = rerased.new_erasing_pair("mapdict storage item")
+erase_map,  unerase_map = rerased.new_erasing_pair("map")
+erase_list, unerase_list = rerased.new_erasing_pair("mapdict storage list")
+
+
 # 
 # attribute shapes
 
@@ -20,6 +25,7 @@
 # note: we use "x * NUM_DIGITS_POW2" instead of "x << NUM_DIGITS" because
 # we want to propagate knowledge that the result cannot be negative
 
+
 class AbstractAttribute(object):
 _immutable_fields_ = ['terminator']
 cache_attrs = None
@@ -151,29 +157,124 

[pypy-commit] pypy py3k: hg merge 0d15dde70904

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: py3k
Changeset: r82437:3a5862bf62c0
Date: 2016-02-23 14:34 +0100
http://bitbucket.org/pypy/pypy/changeset/3a5862bf62c0/

Log:hg merge 0d15dde70904

diff --git a/rpython/jit/backend/ppc/test/test_runner.py 
b/rpython/jit/backend/ppc/test/test_runner.py
--- a/rpython/jit/backend/ppc/test/test_runner.py
+++ b/rpython/jit/backend/ppc/test/test_runner.py
@@ -134,7 +134,7 @@
 
 def test_debugger_on(self):
 py.test.skip("XXX")
-from pypy.rlib import debug
+from rpython.rlib import debug
 
 targettoken, preambletoken = TargetToken(), TargetToken()
 loop = """
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -28,7 +28,7 @@
 # setup rd data
 fi0 = resume.FrameInfo(None, FakeJitCode(), 11)
 snapshot0 = resume.Snapshot(None, [b0])
-op.rd_snapshot = resume.Snapshot(snapshot0, [b1])
+op.rd_snapshot = resume.TopSnapshot(snapshot0, [], [b1])
 op.rd_frame_info_list = resume.FrameInfo(fi0, FakeJitCode(), 33)
 #
 opt.store_final_boxes_in_guard(op, [])
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py 
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -506,14 +506,15 @@
 index = 0
 
 if op.is_guard():
-op.rd_snapshot = resume.Snapshot(None, op.getfailargs())
+op.rd_snapshot = resume.TopSnapshot(
+resume.Snapshot(None, op.getfailargs()), [], [])
 op.rd_frame_info_list = resume.FrameInfo(None, FakeJitCode(), 11)
 
 def add_guard_future_condition(self, res):
 # invent a GUARD_FUTURE_CONDITION to not have to change all tests
 if res.operations[-1].getopnum() == rop.JUMP:
 guard = ResOperation(rop.GUARD_FUTURE_CONDITION, [], None)
-guard.rd_snapshot = resume.Snapshot(None, [])
+guard.rd_snapshot = resume.TopSnapshot(None, [], [])
 res.operations.insert(-1, guard)
 
 def assert_equal(self, optimized, expected, text_right=None):
diff --git a/rpython/jit/metainterp/optimizeopt/util.py 
b/rpython/jit/metainterp/optimizeopt/util.py
--- a/rpython/jit/metainterp/optimizeopt/util.py
+++ b/rpython/jit/metainterp/optimizeopt/util.py
@@ -8,7 +8,7 @@
 from rpython.jit.metainterp import resoperation
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.resume import Snapshot, AccumInfo
+from rpython.jit.metainterp.resume import AccumInfo
 
 # 
 # Misc. utilities
diff --git a/rpython/jit/metainterp/test/strategies.py 
b/rpython/jit/metainterp/test/strategies.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/test/strategies.py
@@ -0,0 +1,13 @@
+
+import sys
+from hypothesis import strategies
+from rpython.jit.metainterp.resoperation import InputArgInt
+from rpython.jit.metainterp.history import ConstInt
+
+machine_ints = strategies.integers(min_value=-sys.maxint - 1,
+max_value=sys.maxint)
+intboxes = strategies.builds(InputArgInt)
+intconsts = strategies.builds(ConstInt, machine_ints)
+boxes = intboxes | intconsts
+boxlists = strategies.lists(boxes, min_size=1).flatmap(
+lambda cis: strategies.lists(strategies.sampled_from(cis)))
\ No newline at end of file
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -25,6 +25,7 @@
 from rpython.jit.metainterp.test.strategies import boxlists
 from rpython.rlib.debug import debug_start, debug_stop, debug_print,\
  have_debug_prints
+from rpython.jit.metainterp import resumecode
 
 from hypothesis import given
 
@@ -1142,7 +1143,8 @@
 class MyInfo:
 @staticmethod
 def enumerate_vars(callback_i, callback_r, callback_f, _, index):
-for tagged in self.numb.code:
+while index < len(self.numb.code):
+tagged, _ = resumecode.numb_next_item(self.numb, index)
 _, tag = untag(tagged)
 if tag == TAGVIRTUAL:
 kind = REF
@@ -1157,6 +1159,13 @@
 index = callback_f(index, index)
 else:
 assert 0
+size, self.cur_index = resumecode.numb_next_item(self.numb, 0)
+assert size == 0
+size, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+assert size == 0
+pc, self.cur_index = 

[pypy-commit] pypy fix-longevity: (remi, plan_rich) lookup of initial binding works on this new branch

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: fix-longevity
Changeset: r82436:099af271b5bc
Date: 2016-02-23 14:13 +0100
http://bitbucket.org/pypy/pypy/changeset/099af271b5bc/

Log:(remi, plan_rich) lookup of initial binding works on this new branch

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -4,7 +4,8 @@
 from rpython.jit.backend.detect_cpu import getcpuclass
 from rpython.jit.backend.x86.arch import DEFAULT_FRAME_BYTES
 from rpython.jit.metainterp.history import TargetToken
-from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.metainterp.resoperation import (rop, ResOperation,
+AbstractValue, CountingDict)
 
 class FakeReg(object):
 def __init__(self, i):
@@ -56,6 +57,7 @@
 def dump(self, *args): pass
 def regalloc_perform(self, *args): pass
 def regalloc_perform_guard(self, *args): pass
+def guard_success_cc(self, *args): pass
 def label(self): pass
 def closing_jump(self, target): pass
 
@@ -88,14 +90,17 @@
 def __init__(self, trace, caller_saved, callee_saved, binding, tt):
 self.trace = trace
 self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
-self.initial_binding = { str(var): reg for var, reg in 
zip(trace.inputargs, binding) }
+self.initial_binding = { var: reg for var, reg in zip(trace.inputargs, 
binding) }
 looptoken = FakeLoopToken()
 gcrefs = []
 tt._x86_arglocs = binding
 
+AbstractValue._repr_memo = CountingDict()
 for op in trace.operations:
 for arg in op.getarglist():
+arg.repr_short(arg._repr_memo)
 pass
+op.repr_short(op._repr_memo)
 self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
 
 for var, reg in zip(trace.inputargs, binding):
@@ -108,8 +113,8 @@
 
 self.regalloc.walk_operations(trace.inputargs, trace.operations)
 
-def initial_register(self, name):
-return self.initial_binding.get(name, None)
+def initial_register(self, var):
+return self.initial_binding.get(var, None)
 
 def move_count(self):
 return len(self.regalloc.assembler.moves)
@@ -118,9 +123,8 @@
 bindings = self.regalloc.rm.reg_bindings
 print bindings
 for var in bindings:
-varname = str(var)
-if varname not in self.initial_binding:
-self.initial_binding[varname] = bindings[var]
+if var not in self.initial_binding:
+self.initial_binding[var] = bindings[var]
 
 class TestRegalloc(object):
 
@@ -135,7 +139,7 @@
 i2 = trace_alloc.initial_register('i2')
 assert i2 == edx
 
-def test_allocate_register_into_jump_register2(self):
+def test_2allocate_register_into_jump_register2(self):
 tt, ops = parse_loop("""
 [p0,i1]
 i2 = int_add(i1,i1)
@@ -143,9 +147,9 @@
 guard_true(i3) []
 jump(p0,i2)
 """)
+i2 = ops.operations[0]
+i3 = ops.operations[1]
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-i2 = trace_alloc.initial_register('i2')
-i3 = trace_alloc.initial_register('i3')
-assert i2 == edx
-assert i3 == r8
+assert trace_alloc.initial_register(i2) == edx
+assert trace_alloc.initial_register(i3) != edx
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-ext: fix

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: cpyext-ext
Changeset: r82435:208a42ce0440
Date: 2016-02-23 13:59 +0100
http://bitbucket.org/pypy/pypy/changeset/208a42ce0440/

Log:fix

diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -539,7 +539,13 @@
 PyObject_Free.api_func.get_wrapper(space))
 pto.c_tp_alloc = llhelper(PyType_GenericAlloc.api_func.functype,
 PyType_GenericAlloc.api_func.get_wrapper(space))
-if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
+builder = space.fromcache(StaticObjectBuilder)
+if ((pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE) != 0
+and builder.cpyext_type_init is None):
+# this ^^^ is not None only during startup of cpyext.  At that
+# point we might get into troubles by doing make_ref() when
+# things are not initialized yet.  So in this case, simply use
+# str2charp() and "leak" the string.
 w_typename = space.getattr(w_type, space.wrap('__name__'))
 heaptype = rffi.cast(PyHeapTypeObject, pto)
 heaptype.c_ht_name = make_ref(space, w_typename)
@@ -554,7 +560,6 @@
 w_base = best_base(space, w_type.bases_w)
 pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base))
 
-builder = space.fromcache(StaticObjectBuilder)
 if builder.cpyext_type_init is not None:
 builder.cpyext_type_init.append((pto, w_type))
 else:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy fix-longevity: (remi, richard) new branch for fixing longevity issue

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: fix-longevity
Changeset: r82434:c464ecd68c54
Date: 2016-02-23 13:58 +0100
http://bitbucket.org/pypy/pypy/changeset/c464ecd68c54/

Log:(remi,richard) new branch for fixing longevity issue

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -0,0 +1,151 @@
+from rpython.jit.tool.oparser import parse
+from rpython.jit.backend.x86.regalloc import RegAlloc
+from rpython.jit.backend.x86.regloc import REGLOCS
+from rpython.jit.backend.detect_cpu import getcpuclass
+from rpython.jit.backend.x86.arch import DEFAULT_FRAME_BYTES
+from rpython.jit.metainterp.history import TargetToken
+from rpython.jit.metainterp.resoperation import rop, ResOperation
+
+class FakeReg(object):
+def __init__(self, i):
+self.n = i
+def __repr__(self):
+return 'r%d' % self.n
+
+eax, ecx, edx, ebx, esp, ebp, esi, edi, r8, r9, r10, r11, r12, r13, r14, r15 = 
REGLOCS
+caller_saved = []
+callee_saved = []
+
+CPU = getcpuclass()
+
+def parse_loop(text):
+ops = parse(text)
+tt = None
+tt = TargetToken(ops.operations[-1].getdescr())
+for op in ops.operations:
+if op.getopnum() == rop.JUMP:
+assert tt is not None
+op.setdescr(tt)
+return tt, ops
+
+class FakeMachineCodeBuilder(object):
+_frame_size = DEFAULT_FRAME_BYTES
+def mark_op(self, op):
+pass
+def get_relative_pos(self): return 0
+def UD2(self): pass
+
+class FakeAssembler(object):
+cpu = CPU(None, None)
+current_clt = None
+target_tokens_currently_compiling = {}
+def __init__(self, regalloc):
+self.mc = FakeMachineCodeBuilder()
+self.regalloc = regalloc
+self.moves = []
+self.pushes = []
+
+def regalloc_mov(self, prev_loc, loc):
+self.moves.append((prev_loc, loc))
+print "mov bindings: ", self.regalloc.rm.reg_bindings
+print prev_loc, "->", loc
+def regalloc_push(self, loc):
+self.pushes.append(loc)
+def regalloc_pop(self, loc):
+pass
+def dump(self, *args): pass
+def regalloc_perform(self, *args): pass
+def regalloc_perform_guard(self, *args): pass
+def label(self): pass
+def closing_jump(self, target): pass
+
+CPURegalloc = RegAlloc
+class FakeRegAlloc(CPURegalloc):
+def __init__(self, tracealloc, caller_saved, callee_saved):
+self.caller_saved = caller_saved
+self.callee_saved = callee_saved
+self.all_regs = caller_saved[:] + callee_saved
+self.free_regs = caller_saved[:] + callee_saved
+CPURegalloc.__init__(self, FakeAssembler(self), False)
+self.tracealloc = tracealloc
+self.steps = set()
+
+def flush_loop(self):
+pass
+
+def possibly_free_vars_for_op(self, op):
+i = self.rm.position
+if i not in self.steps:
+self.steps.add(i)
+self.tracealloc.regalloc_one_step(i)
+CPURegalloc.possibly_free_vars_for_op(self, op)
+
+class FakeLoopToken(object):
+def __init__(self):
+self.compiled_loop_token = None
+
+class TraceAllocation(object):
+def __init__(self, trace, caller_saved, callee_saved, binding, tt):
+self.trace = trace
+self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
+self.initial_binding = { str(var): reg for var, reg in 
zip(trace.inputargs, binding) }
+looptoken = FakeLoopToken()
+gcrefs = []
+tt._x86_arglocs = binding
+
+for op in trace.operations:
+for arg in op.getarglist():
+pass
+self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
+
+for var, reg in zip(trace.inputargs, binding):
+self.regalloc.rm.reg_bindings[var] = reg
+fr = self.regalloc.free_regs
+self.regalloc.rm.free_regs = [reg for reg in fr if reg not in binding]
+
+self.regalloc.rm.all_regs = self.regalloc.all_regs
+self.regalloc.rm.save_around_call_regs = self.regalloc.caller_saved
+
+self.regalloc.walk_operations(trace.inputargs, trace.operations)
+
+def initial_register(self, name):
+return self.initial_binding.get(name, None)
+
+def move_count(self):
+return len(self.regalloc.assembler.moves)
+
+def regalloc_one_step(self, i):
+bindings = self.regalloc.rm.reg_bindings
+print bindings
+for var in bindings:
+varname = str(var)
+if varname not in self.initial_binding:
+self.initial_binding[varname] = bindings[var]
+
+class TestRegalloc(object):
+
+def test_allocate_register_into_jump_register(self):
+tt, ops = parse_loop("""
+[p0,i1]
+i2 = int_add(i1,i1)
+i3 = int_add(i2,i1)
+jump(p0,i2)
+

[pypy-commit] benchmarks single-run: merge default

2016-02-23 Thread fijal
Author: fijal
Branch: single-run
Changeset: r347:ed241f9fde76
Date: 2016-02-23 13:56 +0100
http://bitbucket.org/pypy/benchmarks/changeset/ed241f9fde76/

Log:merge default

diff too long, truncating to 2000 out of 535405 lines

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -59,10 +59,19 @@
 TWISTED = [relative('lib/twisted-trunk'), 
relative('lib/zope.interface-3.5.3/src'), relative('own/twisted')]
 
 opts = {
+'gcbench' : {'iteration_scaling' : .10},
+'pidigits': {'iteration_scaling' : .10},
+'pyxl_bench': {'bm_env': {'PYTHONPATH': relative('lib/pyxl')}},
 'eparse'  : {'bm_env': {'PYTHONPATH': relative('lib/monte')}},
 'bm_mako' : {'bm_env': {'PYTHONPATH': relative('lib/mako')}},
 'bm_dulwich_log': {'bm_env': {'PYTHONPATH': 
relative('lib/dulwich-0.9.1')}},
-'bm_chameleon': {'bm_env': {'PYTHONPATH': relative('lib/chameleon/src')}},
+'bm_chameleon': {'bm_env': {'PYTHONPATH': relative('lib/chameleon/src')},
+ 'iteration_scaling': 3},
+'nqueens': {'iteration_scaling': .1},
+'sqlalchemy_declarative': {'bm_env': {'PYTHONPATH': 
relative('lib/sqlalchemy/lib')},
+   'iteration_scaling': 3},
+'sqlalchemy_imperative': {'bm_env': {'PYTHONPATH': 
relative('lib/sqlalchemy/lib')},
+  'iteration_scaling': 10},
 }
 
 for name in ['expand', 'integrate', 'sum', 'str']:
@@ -80,7 +89,8 @@
  'raytrace-simple', 'crypto_pyaes', 'bm_mako', 'bm_chameleon',
  'json_bench', 'pidigits', 'hexiom2', 'eparse', 'deltablue',
  'bm_dulwich_log', 'bm_krakatau', 'bm_mdp', 'pypy_interp',
- 'bm_icbd']:
+ 'sqlitesynth', 'pyxl_bench', 'nqueens', 'sqlalchemy_declarative',
+ 'sqlalchemy_imperative']:
 _register_new_bm(name, name, globals(), **opts.get(name, {}))
 
 for name in ['names', 'iteration', 'tcp', 'pb', ]:#'web']:#, 'accepts']:
@@ -150,7 +160,8 @@
 logging.info('Running %s', ' '.join(args))
 environ = os.environ.copy()
 environ['PYTHONPATH'] = relative('lib/pypy')
-proc = subprocess.Popen(args, stderr=subprocess.PIPE, env=environ)
+proc = subprocess.Popen(args, stderr=subprocess.PIPE,
+stdout=subprocess.PIPE, env=environ)
 out, err = proc.communicate()
 retcode = proc.poll()
 if retcode != 0:
diff --git a/lib/pypy/rpython/memory/gctransform/shadowstack.py 
b/lib/pypy/rpython/memory/gctransform/shadowstack.py
--- a/lib/pypy/rpython/memory/gctransform/shadowstack.py
+++ b/lib/pypy/rpython/memory/gctransform/shadowstack.py
@@ -400,6 +400,9 @@
 llmemory.raw_free(shadowstackref.base)
 if h:
 _c.destroy(h)
+if not gctransformer.translator.config.translation.continuation:
+def shadowstack_destructor(shadowstackref):
+llmemory.raw_free(shadowstackref.base)
 
 destrptr = gctransformer.annotate_helper(shadowstack_destructor,
  [SHADOWSTACKREFPTR], lltype.Void)
diff --git a/lib/pyxl/LICENSE b/lib/pyxl/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib/pyxl/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+   Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+  "License" shall mean the terms and conditions for use, reproduction,
+  and distribution as defined by Sections 1 through 9 of this document.
+
+  "Licensor" shall mean the copyright owner or entity authorized by
+  the copyright owner that is granting the License.
+
+  "Legal Entity" shall mean the union of the acting entity and all
+  other entities that control, are controlled by, or are under common
+  control with that entity. For the purposes of this definition,
+  "control" means (i) the power, direct or indirect, to cause the
+  direction or management of such entity, whether by contract or
+  otherwise, or (ii) ownership of fifty percent (50%) or more of the
+  outstanding shares, or (iii) beneficial ownership of such entity.
+
+  "You" (or "Your") shall mean an individual or Legal Entity
+  exercising permissions granted by this License.
+
+  "Source" form shall mean the preferred form for making modifications,
+  including but not limited to software source code, documentation
+  source, and configuration files.
+
+  "Object" form shall mean any form resulting from mechanical
+  transformation or translation of a Source form, including but
+  not limited to compiled object code, generated documentation,
+  and conversions to other media types.
+
+  "Work" shall mean the work of authorship, whether in Source or
+  Object form, made available under the License, as indicated by a
+  copyright notice that is included in or 

[pypy-commit] pypy kill-running_on_llinterp: Close superseded branch.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: kill-running_on_llinterp
Changeset: r82433:3edacc8819f9
Date: 2016-02-23 12:45 +0100
http://bitbucket.org/pypy/pypy/changeset/3edacc8819f9/

Log:Close superseded branch.

The goal of this branch was already achieved in the recent llimpl
branch.

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


[pypy-commit] pypy refactor-translator: Close abandoned branch.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: refactor-translator
Changeset: r82432:c7df87defdb6
Date: 2016-02-23 12:43 +0100
http://bitbucket.org/pypy/pypy/changeset/c7df87defdb6/

Log:Close abandoned branch.

I tried to achieve too many things at once in this branch. Some of
the ideas might be reused in new, smaller branches.

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


[pypy-commit] pypy default: Try to fix an import cycle on Windows.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: 
Changeset: r82431:0116c45060a7
Date: 2016-02-23 12:50 +0100
http://bitbucket.org/pypy/pypy/changeset/0116c45060a7/

Log:Try to fix an import cycle on Windows.

diff --git a/rpython/rlib/_os_support.py b/rpython/rlib/_os_support.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/_os_support.py
@@ -0,0 +1,109 @@
+import sys
+
+from rpython.annotator.model import s_Str0, s_Unicode0
+from rpython.rlib import rstring
+from rpython.rlib.objectmodel import specialize
+from rpython.rtyper.lltypesystem import rffi
+
+
+_CYGWIN = sys.platform == 'cygwin'
+_WIN32 = sys.platform.startswith('win')
+UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
+_MACRO_ON_POSIX = True if not _WIN32 else None
+
+
+class StringTraits(object):
+str = str
+str0 = s_Str0
+CHAR = rffi.CHAR
+CCHARP = rffi.CCHARP
+charp2str = staticmethod(rffi.charp2str)
+charpsize2str = staticmethod(rffi.charpsize2str)
+scoped_str2charp = staticmethod(rffi.scoped_str2charp)
+str2charp = staticmethod(rffi.str2charp)
+free_charp = staticmethod(rffi.free_charp)
+scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer)
+
+@staticmethod
+@specialize.argtype(0)
+def as_str(path):
+assert path is not None
+if isinstance(path, str):
+return path
+elif isinstance(path, unicode):
+# This never happens in PyPy's Python interpreter!
+# Only in raw RPython code that uses unicode strings.
+# We implement python2 behavior: silently convert to ascii.
+return path.encode('ascii')
+else:
+return path.as_bytes()
+
+@staticmethod
+@specialize.argtype(0)
+def as_str0(path):
+res = StringTraits.as_str(path)
+rstring.check_str0(res)
+return res
+
+
+class UnicodeTraits(object):
+str = unicode
+str0 = s_Unicode0
+CHAR = rffi.WCHAR_T
+CCHARP = rffi.CWCHARP
+charp2str = staticmethod(rffi.wcharp2unicode)
+charpsize2str = staticmethod(rffi.wcharpsize2unicode)
+str2charp = staticmethod(rffi.unicode2wcharp)
+scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp)
+free_charp = staticmethod(rffi.free_wcharp)
+scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer)
+
+@staticmethod
+@specialize.argtype(0)
+def as_str(path):
+assert path is not None
+if isinstance(path, unicode):
+return path
+else:
+return path.as_unicode()
+
+@staticmethod
+@specialize.argtype(0)
+def as_str0(path):
+res = UnicodeTraits.as_str(path)
+rstring.check_str0(res)
+return res
+
+
+string_traits = StringTraits()
+unicode_traits = UnicodeTraits()
+
+
+# Returns True when the unicode function should be called:
+# - on Windows
+# - if the path is Unicode.
+if _WIN32:
+@specialize.argtype(0)
+def _prefer_unicode(path):
+assert path is not None
+if isinstance(path, str):
+return False
+elif isinstance(path, unicode):
+return True
+else:
+return path.is_unicode
+
+@specialize.argtype(0)
+def _preferred_traits(path):
+if _prefer_unicode(path):
+return unicode_traits
+else:
+return string_traits
+else:
+@specialize.argtype(0)
+def _prefer_unicode(path):
+return False
+
+@specialize.argtype(0)
+def _preferred_traits(path):
+return string_traits
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1,26 +1,22 @@
 import os
 import sys
 import errno
+from rpython.annotator.model import s_Str0
 from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT
 from rpython.rtyper.lltypesystem import lltype, ll2ctypes, rffi
 from rpython.rtyper.tool import rffi_platform
-from rpython.tool.sourcetools import func_renamer
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rlib.rarithmetic import intmask, widen
+from rpython.rlib import debug, jit, rstring, rthread, types
+from rpython.rlib._os_support import (
+_CYGWIN, _MACRO_ON_POSIX, UNDERSCORE_ON_WIN32, _WIN32,
+_prefer_unicode, _preferred_traits)
 from rpython.rlib.objectmodel import (
 specialize, enforceargs, register_replacement_for, NOT_CONSTANT)
+from rpython.rlib.rarithmetic import intmask, widen
 from rpython.rlib.signature import signature
-from rpython.rlib import types
-from rpython.annotator.model import s_Str0, s_Unicode0
-from rpython.rlib import jit
+from rpython.tool.sourcetools import func_renamer
 from rpython.translator.platform import platform
-from rpython.rlib import rstring
-from rpython.rlib import debug, rthread
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
-_WIN32 = sys.platform.startswith('win')
-_CYGWIN = sys.platform == 'cygwin'
-UNDERSCORE_ON_WIN32 

[pypy-commit] pypy default: Kill unused ll_os_name() method.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: 
Changeset: r82430:a70ddbff44ec
Date: 2016-02-23 11:55 +0100
http://bitbucket.org/pypy/pypy/changeset/a70ddbff44ec/

Log:Kill unused ll_os_name() method.

diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -355,10 +355,6 @@
 scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer)
 
 @staticmethod
-def ll_os_name(name):
-return 'll_os.ll_os_' + name
-
-@staticmethod
 @specialize.argtype(0)
 def as_str(path):
 assert path is not None
@@ -394,11 +390,6 @@
 
 @staticmethod
 @specialize.argtype(0)
-def ll_os_name(name):
-return 'll_os.ll_os_w' + name
-
-@staticmethod
-@specialize.argtype(0)
 def as_str(path):
 assert path is not None
 if isinstance(path, unicode):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Kill unused posix_function_name() method.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: 
Changeset: r82429:b6338ee2fffb
Date: 2016-02-23 11:51 +0100
http://bitbucket.org/pypy/pypy/changeset/b6338ee2fffb/

Log:Kill unused posix_function_name() method.

diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -355,10 +355,6 @@
 scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer)
 
 @staticmethod
-def posix_function_name(name):
-return UNDERSCORE_ON_WIN32 + name
-
-@staticmethod
 def ll_os_name(name):
 return 'll_os.ll_os_' + name
 
@@ -397,10 +393,6 @@
 scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer)
 
 @staticmethod
-def posix_function_name(name):
-return UNDERSCORE_ON_WIN32 + 'w' + name
-
-@staticmethod
 @specialize.argtype(0)
 def ll_os_name(name):
 return 'll_os.ll_os_w' + name
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy regalloc: (remi,richard) another failing test

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: regalloc
Changeset: r82428:aef33cf7c7d2
Date: 2016-02-23 12:54 +0100
http://bitbucket.org/pypy/pypy/changeset/aef33cf7c7d2/

Log:(remi,richard) another failing test

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -37,22 +37,24 @@
 cpu = CPU(None, None)
 current_clt = None
 target_tokens_currently_compiling = {}
-def __init__(self):
+def __init__(self, regalloc):
 self.mc = FakeMachineCodeBuilder()
+self.regalloc = regalloc
 self.moves = []
 self.pushes = []
 
 def regalloc_mov(self, prev_loc, loc):
 self.moves.append((prev_loc, loc))
+print "mov bindings: ", self.regalloc.rm.reg_bindings
+print prev_loc, "->", loc
 def regalloc_push(self, loc):
 import pdb; pdb.set_trace()
 self.pushes.append(loc)
 def regalloc_pop(self, loc):
 pass
-
-def regalloc_mov(self, prev, loc): pass
 def dump(self, *args): pass
 def regalloc_perform(self, *args): pass
+def regalloc_perform_guard(self, *args): pass
 def label(self): pass
 def closing_jump(self, target): pass
 
@@ -63,7 +65,7 @@
 self.callee_saved = callee_saved
 self.all_regs = caller_saved[:] + callee_saved
 self.free_regs = caller_saved[:] + callee_saved
-CPURegalloc.__init__(self, FakeAssembler(), False)
+CPURegalloc.__init__(self, FakeAssembler(self), False)
 self.tracealloc = tracealloc
 self.steps = set()
 
@@ -87,7 +89,7 @@
 self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
 self.initial_binding = { str(var): reg for var, reg in 
zip(trace.inputargs, binding) }
 looptoken = FakeLoopToken()
-gcrefs = None
+gcrefs = []
 tt._x86_arglocs = binding
 
 for op in trace.operations:
@@ -113,6 +115,7 @@
 
 def regalloc_one_step(self, i):
 bindings = self.regalloc.rm.reg_bindings
+print bindings
 for var in bindings:
 varname = str(var)
 if varname not in self.initial_binding:
@@ -122,15 +125,26 @@
 
 def test_allocate_register_into_jump_register(self):
 tt, ops = parse_loop("""
-[i0,i1]
-i2 = int_add(i0,i1)
+[p0,i1]
+i2 = int_add(i1,i1)
 i3 = int_add(i2,i1)
-i4 = int_add(i3,i0)
-jump(i4,i2)
+jump(p0,i2)
 """)
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-assert trace_alloc.initial_register('i2') == edx
-assert trace_alloc.initial_register('i0') == eax
-assert trace_alloc.initial_register('i4') == eax
-assert trace_alloc.move_count() == 0
+i2 = trace_alloc.initial_register('i2')
+assert i2 == edx
 
+def test_allocate_register_into_jump_register2(self):
+tt, ops = parse_loop("""
+[p0,i1]
+i2 = int_add(i1,i1)
+i3 = int_add(i2,i1)
+guard_true(i3) []
+jump(p0,i2)
+""")
+trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
+i2 = trace_alloc.initial_register('i2')
+i3 = trace_alloc.initial_register('i3')
+assert i2 == edx
+assert i3 == r8
+
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy regalloc: (remi, plan_rich) changed the test case to force reordering at jump

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: regalloc
Changeset: r82427:82e72df75cb3
Date: 2016-02-23 12:35 +0100
http://bitbucket.org/pypy/pypy/changeset/82e72df75cb3/

Log:(remi, plan_rich) changed the test case to force reordering at jump

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -39,6 +39,17 @@
 target_tokens_currently_compiling = {}
 def __init__(self):
 self.mc = FakeMachineCodeBuilder()
+self.moves = []
+self.pushes = []
+
+def regalloc_mov(self, prev_loc, loc):
+self.moves.append((prev_loc, loc))
+def regalloc_push(self, loc):
+import pdb; pdb.set_trace()
+self.pushes.append(loc)
+def regalloc_pop(self, loc):
+pass
+
 def regalloc_mov(self, prev, loc): pass
 def dump(self, *args): pass
 def regalloc_perform(self, *args): pass
@@ -97,6 +108,9 @@
 def initial_register(self, name):
 return self.initial_binding.get(name, None)
 
+def move_count(self):
+return len(self.regalloc.assembler.moves)
+
 def regalloc_one_step(self, i):
 bindings = self.regalloc.rm.reg_bindings
 for var in bindings:
@@ -108,12 +122,15 @@
 
 def test_allocate_register_into_jump_register(self):
 tt, ops = parse_loop("""
-[p0,i1]
-i2 = int_add(i1,i1)
+[i0,i1]
+i2 = int_add(i0,i1)
 i3 = int_add(i2,i1)
-jump(p0,i2)
+i4 = int_add(i3,i0)
+jump(i4,i2)
 """)
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
-i2 = trace_alloc.initial_register('i2')
-assert i2 == edx
+assert trace_alloc.initial_register('i2') == edx
+assert trace_alloc.initial_register('i0') == eax
+assert trace_alloc.initial_register('i4') == eax
+assert trace_alloc.move_count() == 0
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-gc-support-2: Kill debug prints

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: cpyext-gc-support-2
Changeset: r82425:721c1e322b76
Date: 2016-02-23 12:06 +0100
http://bitbucket.org/pypy/pypy/changeset/721c1e322b76/

Log:Kill debug prints

diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py 
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -533,7 +533,7 @@
 # Ctypes-aware subclasses of the _parentable classes
 
 ALLOCATED = {} # mapping {address: _container}
-DEBUG_ALLOCATED = True
+DEBUG_ALLOCATED = False
 
 def get_common_subclass(cls1, cls2, cache={}):
 """Return a unique subclass with (cls1, cls2) as bases."""
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: hg merge cpyext-gc-support-2

2016-02-23 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r82426:3144c72295ae
Date: 2016-02-23 12:08 +0100
http://bitbucket.org/pypy/pypy/changeset/3144c72295ae/

Log:hg merge cpyext-gc-support-2

Use a more stable approach for allocating PyObjects in cpyext: once
the PyObject corresponding to a PyPy object is created, it stays
around at the same location until the death of the PyPy object. Done
with a little bit of custom GC support. It allows us to kill the
notion of "borrowing" inside cpyext, and reduces 4 dictionaries down
to 1.

diff too long, truncating to 2000 out of 5064 lines

diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -7,6 +7,7 @@
 content = fid.read()
 # from cffi's Verifier()
 key = '\x00'.join([sys.version[:3], content])
+key += 'cpyext-gc-support-2'   # this branch requires recompilation!
 if sys.version_info >= (3,):
 key = key.encode('utf-8')
 k1 = hex(binascii.crc32(key[0::2]) & 0x)
diff --git a/pypy/doc/discussion/rawrefcount.rst 
b/pypy/doc/discussion/rawrefcount.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussion/rawrefcount.rst
@@ -0,0 +1,158 @@
+==
+Rawrefcount and the GC
+==
+
+
+GC Interface
+
+
+"PyObject" is a raw structure with at least two fields, ob_refcnt and
+ob_pypy_link.  The ob_refcnt is the reference counter as used on
+CPython.  If the PyObject structure is linked to a live PyPy object,
+its current address is stored in ob_pypy_link and ob_refcnt is bumped
+by either the constant REFCNT_FROM_PYPY, or the constant
+REFCNT_FROM_PYPY_LIGHT (== REFCNT_FROM_PYPY + SOME_HUGE_VALUE)
+(to mean "light finalizer").
+
+Most PyPy objects exist outside cpyext, and conversely in cpyext it is
+possible that a lot of PyObjects exist without being seen by the rest
+of PyPy.  At the interface, however, we can "link" a PyPy object and a
+PyObject.  There are two kinds of link:
+
+rawrefcount.create_link_pypy(p, ob)
+
+Makes a link between an exising object gcref 'p' and a newly
+allocated PyObject structure 'ob'.  ob->ob_refcnt must be
+initialized to either REFCNT_FROM_PYPY, or
+REFCNT_FROM_PYPY_LIGHT.  (The second case is an optimization:
+when the GC finds the PyPy object and PyObject no longer
+referenced, it can just free() the PyObject.)
+
+rawrefcount.create_link_pyobj(p, ob)
+
+Makes a link from an existing PyObject structure 'ob' to a newly
+allocated W_CPyExtPlaceHolderObject 'p'.  You must also add
+REFCNT_FROM_PYPY to ob->ob_refcnt.  For cases where the PyObject
+contains all the data, and the PyPy object is just a proxy.  The
+W_CPyExtPlaceHolderObject should have only a field that contains
+the address of the PyObject, but that's outside the scope of the
+GC.
+
+rawrefcount.from_obj(p)
+
+If there is a link from object 'p' made with create_link_pypy(),
+returns the corresponding 'ob'.  Otherwise, returns NULL.
+
+rawrefcount.to_obj(Class, ob)
+
+Returns ob->ob_pypy_link, cast to an instance of 'Class'.
+
+
+Collection logic
+
+
+Objects existing purely on the C side have ob->ob_pypy_link == 0;
+these are purely reference counted.  On the other hand, if
+ob->ob_pypy_link != 0, then ob->ob_refcnt is at least REFCNT_FROM_PYPY
+and the object is part of a "link".
+
+The idea is that links whose 'p' is not reachable from other PyPy
+objects *and* whose 'ob->ob_refcnt' is REFCNT_FROM_PYPY or
+REFCNT_FROM_PYPY_LIGHT are the ones who die.  But it is more messy
+because PyObjects still (usually) need to have a tp_dealloc called,
+and this cannot occur immediately (and can do random things like
+accessing other references this object points to, or resurrecting the
+object).
+
+Let P = list of links created with rawrefcount.create_link_pypy()
+and O = list of links created with rawrefcount.create_link_pyobj().
+The PyPy objects in the list O are all W_CPyExtPlaceHolderObject: all
+the data is in the PyObjects, and all outsite references (if any) are
+in C, as "PyObject *" fields.
+
+So, during the collection we do this about P links:
+
+for (p, ob) in P:
+if ob->ob_refcnt != REFCNT_FROM_PYPY
+   and ob->ob_refcnt != REFCNT_FROM_PYPY_LIGHT:
+mark 'p' as surviving, as well as all its dependencies
+
+At the end of the collection, the P and O links are both handled like
+this:
+
+for (p, ob) in P + O:
+if p is not surviving:# even if 'ob' might be surviving
+unlink p and ob
+if ob->ob_refcnt == REFCNT_FROM_PYPY_LIGHT:
+free(ob)
+elif ob->ob_refcnt > REFCNT_FROM_PYPY_LIGHT:
+ob->ob_refcnt -= REFCNT_FROM_PYPY_LIGHT
+else:
+ob->ob_refcnt -= REFCNT_FROM_PYPY
+if ob->ob_refcnt == 0:
+

[pypy-commit] pypy regalloc: (remi, plan_rich) reordering seems to work for the first test case

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: regalloc
Changeset: r82424:84ffabb00046
Date: 2016-02-23 12:05 +0100
http://bitbucket.org/pypy/pypy/changeset/84ffabb00046/

Log:(remi, plan_rich) reordering seems to work for the first test case

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -50,8 +50,8 @@
 def __init__(self, tracealloc, caller_saved, callee_saved):
 self.caller_saved = caller_saved
 self.callee_saved = callee_saved
-self.all_regs = callee_saved[:] + callee_saved
-self.free_regs = callee_saved[:] + callee_saved
+self.all_regs = caller_saved[:] + callee_saved
+self.free_regs = caller_saved[:] + callee_saved
 CPURegalloc.__init__(self, FakeAssembler(), False)
 self.tracealloc = tracealloc
 self.steps = set()
@@ -64,6 +64,7 @@
 if i not in self.steps:
 self.steps.add(i)
 self.tracealloc.regalloc_one_step(i)
+CPURegalloc.possibly_free_vars_for_op(self, op)
 
 class FakeLoopToken(object):
 def __init__(self):
@@ -83,10 +84,9 @@
 pass
 self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
 
-
 for var, reg in zip(trace.inputargs, binding):
 self.regalloc.rm.reg_bindings[var] = reg
-fr = self.regalloc.rm.free_regs
+fr = self.regalloc.free_regs
 self.regalloc.rm.free_regs = [reg for reg in fr if reg not in binding]
 
 self.regalloc.rm.all_regs = self.regalloc.all_regs
@@ -115,6 +115,5 @@
 """)
 trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
 i2 = trace_alloc.initial_register('i2')
-i1 = trace_alloc.initial_register('i1')
-assert i2 == i1
+assert i2 == edx
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy regalloc: (remi, plan_rich) work in progress

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: regalloc
Changeset: r82423:f8ee5bddeb4b
Date: 2016-02-23 11:53 +0100
http://bitbucket.org/pypy/pypy/changeset/f8ee5bddeb4b/

Log:(remi, plan_rich) work in progress

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -1,5 +1,6 @@
 from rpython.jit.tool.oparser import parse
 from rpython.jit.backend.x86.regalloc import RegAlloc
+from rpython.jit.backend.x86.regloc import REGLOCS
 from rpython.jit.backend.detect_cpu import getcpuclass
 from rpython.jit.backend.x86.arch import DEFAULT_FRAME_BYTES
 from rpython.jit.metainterp.history import TargetToken
@@ -11,7 +12,9 @@
 def __repr__(self):
 return 'r%d' % self.n
 
-r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 = [FakeReg(i) for i in range(1,11)]
+eax, ecx, edx, ebx, esp, ebp, esi, edi, r8, r9, r10, r11, r12, r13, r14, r15 = 
REGLOCS
+caller_saved = []
+callee_saved = []
 
 CPU = getcpuclass()
 
@@ -19,12 +22,11 @@
 ops = parse(text)
 tt = None
 tt = TargetToken(ops.operations[-1].getdescr())
-ops.operations = [ResOperation(rop.LABEL, ops.inputargs, None, descr=tt)] 
+ ops.operations
 for op in ops.operations:
 if op.getopnum() == rop.JUMP:
 assert tt is not None
 op.setdescr(tt)
-return ops
+return tt, ops
 
 class FakeMachineCodeBuilder(object):
 _frame_size = DEFAULT_FRAME_BYTES
@@ -46,7 +48,10 @@
 CPURegalloc = RegAlloc
 class FakeRegAlloc(CPURegalloc):
 def __init__(self, tracealloc, caller_saved, callee_saved):
+self.caller_saved = caller_saved
+self.callee_saved = callee_saved
 self.all_regs = callee_saved[:] + callee_saved
+self.free_regs = callee_saved[:] + callee_saved
 CPURegalloc.__init__(self, FakeAssembler(), False)
 self.tracealloc = tracealloc
 self.steps = set()
@@ -65,16 +70,28 @@
 self.compiled_loop_token = None
 
 class TraceAllocation(object):
-def __init__(self, trace, caller_saved, callee_saved, binding):
+def __init__(self, trace, caller_saved, callee_saved, binding, tt):
 self.trace = trace
 self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
-self.initial_binding = binding
+self.initial_binding = { str(var): reg for var, reg in 
zip(trace.inputargs, binding) }
 looptoken = FakeLoopToken()
 gcrefs = None
+tt._x86_arglocs = binding
+
 for op in trace.operations:
 for arg in op.getarglist():
 pass
 self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
+
+
+for var, reg in zip(trace.inputargs, binding):
+self.regalloc.rm.reg_bindings[var] = reg
+fr = self.regalloc.rm.free_regs
+self.regalloc.rm.free_regs = [reg for reg in fr if reg not in binding]
+
+self.regalloc.rm.all_regs = self.regalloc.all_regs
+self.regalloc.rm.save_around_call_regs = self.regalloc.caller_saved
+
 self.regalloc.walk_operations(trace.inputargs, trace.operations)
 
 def initial_register(self, name):
@@ -90,13 +107,13 @@
 class TestRegalloc(object):
 
 def test_allocate_register_into_jump_register(self):
-ops = parse_loop("""
+tt, ops = parse_loop("""
 [p0,i1]
 i2 = int_add(i1,i1)
 i3 = int_add(i2,i1)
 jump(p0,i2)
 """)
-trace_alloc = TraceAllocation(ops, [r1, r2], [r3, r4], {'p0': r1, 
'i1': r2})
+trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], 
tt)
 i2 = trace_alloc.initial_register('i2')
 i1 = trace_alloc.initial_register('i1')
 assert i2 == i1
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] buildbot default: whoops for windows

2016-02-23 Thread mattip
Author: mattip 
Branch: 
Changeset: r989:84b6181d15c1
Date: 2016-02-23 11:46 +0100
http://bitbucket.org/pypy/buildbot/changeset/84b6181d15c1/

Log:whoops for windows

diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py
--- a/bot2/pypybuildbot/builds.py
+++ b/bot2/pypybuildbot/builds.py
@@ -534,7 +534,7 @@
 ))
 
 if platform == 'win32':
-virt_python = 'virt_test/Scripts/python'
+virt_python = r'virt_test\Scripts\python.exe'
 else:
 virt_python = 'virt_test/bin/python'
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: (fijal, cfbolz) finish fixing tests

2016-02-23 Thread fijal
Author: fijal
Branch: 
Changeset: r82422:0d15dde70904
Date: 2016-02-23 11:27 +0100
http://bitbucket.org/pypy/pypy/changeset/0d15dde70904/

Log:(fijal, cfbolz) finish fixing tests

diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py 
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -514,7 +514,7 @@
 # invent a GUARD_FUTURE_CONDITION to not have to change all tests
 if res.operations[-1].getopnum() == rop.JUMP:
 guard = ResOperation(rop.GUARD_FUTURE_CONDITION, [], None)
-guard.rd_snapshot = resume.Snapshot(None, [])
+guard.rd_snapshot = resume.TopSnapshot(None, [], [])
 res.operations.insert(-1, guard)
 
 def assert_equal(self, optimized, expected, text_right=None):
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -25,6 +25,7 @@
 from rpython.jit.metainterp.test.strategies import boxlists
 from rpython.rlib.debug import debug_start, debug_stop, debug_print,\
  have_debug_prints
+from rpython.jit.metainterp import resumecode
 
 from hypothesis import given
 
@@ -1142,7 +1143,8 @@
 class MyInfo:
 @staticmethod
 def enumerate_vars(callback_i, callback_r, callback_f, _, index):
-for tagged in self.numb.code:
+while index < len(self.numb.code):
+tagged, _ = resumecode.numb_next_item(self.numb, index)
 _, tag = untag(tagged)
 if tag == TAGVIRTUAL:
 kind = REF
@@ -1157,6 +1159,13 @@
 index = callback_f(index, index)
 else:
 assert 0
+size, self.cur_index = resumecode.numb_next_item(self.numb, 0)
+assert size == 0
+size, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+assert size == 0
+pc, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+jitcode_pos, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+
 self._prepare_next_section(MyInfo())
 return self.lst
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cpyext-ext: merge cpyext-gc-support-2 into branch

2016-02-23 Thread mattip
Author: mattip 
Branch: cpyext-ext
Changeset: r82421:0b974f24de3d
Date: 2016-02-23 11:14 +0100
http://bitbucket.org/pypy/pypy/changeset/0b974f24de3d/

Log:merge cpyext-gc-support-2 into branch

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -22,6 +22,7 @@
 ^pypy/module/cpyext/test/.+\.obj$
 ^pypy/module/cpyext/test/.+\.manifest$
 ^pypy/module/test_lib_pypy/ctypes_tests/.+\.o$
+^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$
 ^pypy/module/cppyy/src/.+\.o$
 ^pypy/module/cppyy/bench/.+\.so$
 ^pypy/module/cppyy/bench/.+\.root$
@@ -35,7 +36,6 @@
 ^pypy/module/test_lib_pypy/cffi_tests/__pycache__.+$
 ^pypy/doc/.+\.html$
 ^pypy/doc/config/.+\.rst$
-^pypy/doc/basicblock\.asc$
 ^pypy/doc/.+\.svninfo$
 ^rpython/translator/c/src/libffi_msvc/.+\.obj$
 ^rpython/translator/c/src/libffi_msvc/.+\.dll$
@@ -45,53 +45,33 @@
 ^rpython/translator/c/src/cjkcodecs/.+\.obj$
 ^rpython/translator/c/src/stacklet/.+\.o$
 ^rpython/translator/c/src/.+\.o$
-^rpython/translator/jvm/\.project$
-^rpython/translator/jvm/\.classpath$
-^rpython/translator/jvm/eclipse-bin$
-^rpython/translator/jvm/src/pypy/.+\.class$
-^rpython/translator/benchmark/docutils$
-^rpython/translator/benchmark/templess$
-^rpython/translator/benchmark/gadfly$
-^rpython/translator/benchmark/mako$
-^rpython/translator/benchmark/bench-custom\.benchmark_result$
-^rpython/translator/benchmark/shootout_benchmarks$
+^rpython/translator/llvm/.+\.so$
 ^rpython/translator/goal/target.+-c$
 ^rpython/translator/goal/.+\.exe$
 ^rpython/translator/goal/.+\.dll$
 ^pypy/goal/pypy-translation-snapshot$
 ^pypy/goal/pypy-c
-^pypy/goal/pypy-jvm
-^pypy/goal/pypy-jvm.jar
 ^pypy/goal/.+\.exe$
 ^pypy/goal/.+\.dll$
 ^pypy/goal/.+\.lib$
 ^pypy/_cache$
-^pypy/doc/statistic/.+\.html$
-^pypy/doc/statistic/.+\.eps$
-^pypy/doc/statistic/.+\.pdf$
-^rpython/translator/cli/src/pypylib\.dll$
-^rpython/translator/cli/src/query\.exe$
-^rpython/translator/cli/src/main\.exe$
+^lib-python/2.7/lib2to3/.+\.pickle$
 ^lib_pypy/__pycache__$
 ^lib_pypy/ctypes_config_cache/_.+_cache\.py$
 ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$
 ^lib_pypy/_libmpdec/.+.o$
-^rpython/translator/cli/query-descriptions$
 ^pypy/doc/discussion/.+\.html$
 ^include/.+\.h$
 ^include/.+\.inl$
 ^pypy/doc/_build/.*$
 ^pypy/doc/config/.+\.html$
 ^pypy/doc/config/style\.css$
-^pypy/doc/jit/.+\.html$
-^pypy/doc/jit/style\.css$
 ^pypy/doc/image/lattice1\.png$
 ^pypy/doc/image/lattice2\.png$
 ^pypy/doc/image/lattice3\.png$
 ^pypy/doc/image/stackless_informal\.png$
 ^pypy/doc/image/parsing_example.+\.png$
 ^rpython/doc/_build/.*$
-^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$
 ^compiled
 ^.git/
 ^release/
diff --git a/pypy/interpreter/pyparser/pytokenizer.py 
b/pypy/interpreter/pyparser/pytokenizer.py
--- a/pypy/interpreter/pyparser/pytokenizer.py
+++ b/pypy/interpreter/pyparser/pytokenizer.py
@@ -91,6 +91,7 @@
 strstart = (0, 0, "")
 for line in lines:
 lnum = lnum + 1
+line = universal_newline(line)
 pos, max = 0, len(line)
 
 if contstr:
@@ -259,3 +260,14 @@
 
 token_list.append((tokens.ENDMARKER, '', lnum, pos, line))
 return token_list
+
+
+def universal_newline(line):
+# show annotator that indexes below are non-negative
+line_len_m2 = len(line) - 2
+if line_len_m2 >= 0 and line[-2] == '\r' and line[-1] == '\n':
+return line[:line_len_m2] + '\n'
+line_len_m1 = len(line) - 1
+if line_len_m1 >= 0 and line[-1] == '\r':
+return line[:line_len_m1] + '\n'
+return line
diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py 
b/pypy/interpreter/pyparser/test/test_pyparse.py
--- a/pypy/interpreter/pyparser/test/test_pyparse.py
+++ b/pypy/interpreter/pyparser/test/test_pyparse.py
@@ -158,3 +158,10 @@
 
 def test_print_function(self):
 self.parse("from __future__ import print_function\nx = print\n")
+
+def test_universal_newlines(self):
+fmt = 'stuff = """hello%sworld"""'
+expected_tree = self.parse(fmt % '\n')
+for linefeed in ["\r\n","\r"]:
+tree = self.parse(fmt % linefeed)
+assert expected_tree == tree
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -156,20 +156,6 @@
 get_unique_interplevel_subclass._annspecialcase_ = "specialize:memo"
 _subclass_cache = {}
 
-def enum_interplevel_subclasses(config, cls):
-"""Return a list of all the extra interp-level subclasses of 'cls' that
-can be built by get_unique_interplevel_subclass()."""
-result = []
-for flag1 in (False, True):
-for flag2 in (False, True):
-for flag3 in (False, True):
-for flag4 in (False, True):
-result.append(get_unique_interplevel_subclass(
-config, cls, flag1, flag2, flag3, flag4))
-result = dict.fromkeys(result)
-assert len(result) <= 6
-return result.keys()
-

[pypy-commit] pypy regalloc: progress on faking the reg alloc for testing internal properties

2016-02-23 Thread plan_rich
Author: Richard Plangger 
Branch: regalloc
Changeset: r82420:b765f3e0ddd4
Date: 2016-02-23 11:11 +0100
http://bitbucket.org/pypy/pypy/changeset/b765f3e0ddd4/

Log:progress on faking the reg alloc for testing internal properties

diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py
@@ -45,10 +45,20 @@
 
 CPURegalloc = RegAlloc
 class FakeRegAlloc(CPURegalloc):
-def __init__(self, caller_saved, callee_saved):
+def __init__(self, tracealloc, caller_saved, callee_saved):
 self.all_regs = callee_saved[:] + callee_saved
 CPURegalloc.__init__(self, FakeAssembler(), False)
-def flush_loop(self): pass
+self.tracealloc = tracealloc
+self.steps = set()
+
+def flush_loop(self):
+pass
+
+def possibly_free_vars_for_op(self, op):
+i = self.rm.position
+if i not in self.steps:
+self.steps.add(i)
+self.tracealloc.regalloc_one_step(i)
 
 class FakeLoopToken(object):
 def __init__(self):
@@ -57,19 +67,25 @@
 class TraceAllocation(object):
 def __init__(self, trace, caller_saved, callee_saved, binding):
 self.trace = trace
-self.regalloc = FakeRegAlloc(caller_saved, callee_saved)
+self.regalloc = FakeRegAlloc(self, caller_saved, callee_saved)
 self.initial_binding = binding
 looptoken = FakeLoopToken()
 gcrefs = None
 for op in trace.operations:
 for arg in op.getarglist():
 pass
-pass
 self.regalloc.prepare_loop(self.trace.inputargs, 
self.trace.operations, looptoken, gcrefs)
 self.regalloc.walk_operations(trace.inputargs, trace.operations)
 
 def initial_register(self, name):
-pass
+return self.initial_binding.get(name, None)
+
+def regalloc_one_step(self, i):
+bindings = self.regalloc.rm.reg_bindings
+for var in bindings:
+varname = str(var)
+if varname not in self.initial_binding:
+self.initial_binding[varname] = bindings[var]
 
 class TestRegalloc(object):
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c8: fix

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: stmgc-c8
Changeset: r82419:52371edbd322
Date: 2016-02-23 10:59 +0100
http://bitbucket.org/pypy/pypy/changeset/52371edbd322/

Log:fix

diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py
--- a/pypy/module/thread/__init__.py
+++ b/pypy/module/thread/__init__.py
@@ -27,7 +27,7 @@
 prev_ec = space.threadlocals.get_ec()
 if space.config.translation.stm:
 from pypy.module.thread import stm
-space.threadlocals = stm.STMThreadLocals()
+space.threadlocals = stm.STMThreadLocals(space)
 else:
 from pypy.module.thread import gil
 space.threadlocals = gil.GILThreadLocals(space)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c8: Next merge with default

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: stmgc-c8
Changeset: r82417:3522d0e0b4ac
Date: 2016-02-22 23:49 +0100
http://bitbucket.org/pypy/pypy/changeset/3522d0e0b4ac/

Log:Next merge with default

diff too long, truncating to 2000 out of 5350 lines

diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -29,4 +29,4 @@
 release/
 !pypy/tool/release/
 rpython/_cache/
-__pycache__/
+.cache/
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -28,7 +28,7 @@
 DEALINGS IN THE SOFTWARE.
 
 
-PyPy Copyright holders 2003-2015
+PyPy Copyright holders 2003-2016
 --- 
 
 Except when otherwise stated (look for LICENSE files or information at
diff --git a/lib-python/2.7/pickle.py b/lib-python/2.7/pickle.py
--- a/lib-python/2.7/pickle.py
+++ b/lib-python/2.7/pickle.py
@@ -1376,6 +1376,7 @@
 
 def decode_long(data):
 r"""Decode a long from a two's complement little-endian binary string.
+This is overriden on PyPy by a RPython version that has linear complexity.
 
 >>> decode_long('')
 0L
@@ -1402,6 +1403,11 @@
 n -= 1L << (nbytes * 8)
 return n
 
+try:
+from __pypy__ import decode_long
+except ImportError:
+pass
+
 # Shorthands
 
 try:
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cffi
-Version: 1.4.0
+Version: 1.4.2
 Summary: Foreign Function Interface for Python calling C code.
 Home-page: http://cffi.readthedocs.org
 Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.4.0"
-__version_info__ = (1, 4, 0)
+__version__ = "1.4.2"
+__version_info__ = (1, 4, 2)
 
 # The verifier module file names are based on the CRC32 of a string that
 # contains the following version number.  It may be older than __version__
diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst
--- a/pypy/doc/embedding.rst
+++ b/pypy/doc/embedding.rst
@@ -130,8 +130,13 @@
 More complete example
 -
 
-.. note:: This example depends on pypy_execute_source_ptr which is not 
available
-  in PyPy <= 2.2.1.
+.. note:: Note that we do not make use of ``extern "Python"``, the new
+   way to do callbacks in CFFI 1.4: this is because these examples use
+   the ABI mode, not the API mode, and with the ABI mode you still have
+   to use ``ffi.callback()``.  It is work in progress to integrate
+   ``extern "Python"`` with the idea of embedding (and it is expected
+   to ultimately lead to a better way to do embedding than the one
+   described here, and that would work equally well on CPython and PyPy).
 
 Typically we need something more to do than simply execute source. The 
following
 is a fully fledged example, please consult cffi documentation for details.
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
@@ -5,6 +5,8 @@
 .. this is a revision shortly after release-4.0.1
 .. startrev: 4b5c840d0da2
 
+Fixed ``_PyLong_FromByteArray()``, which was buggy.
+
 .. branch: numpy-1.10
 
 Fix tests to run cleanly with -A and start to fix micronumpy for upstream numpy
@@ -44,6 +46,9 @@
 
 .. branch: fix-setslice-can-resize
 
+Make rlist's ll_listsetslice() able to resize the target list to help
+simplify objspace/std/listobject.py. Was issue #2196.
+
 .. branch: anntype2
 
 A somewhat random bunch of changes and fixes following up on branch 'anntype'. 
Highlights:
@@ -77,3 +82,24 @@
 .. branch: always-enable-gil
 
 Simplify a bit the GIL handling in non-jitted code.  Fixes issue #2205.
+
+.. branch: flowspace-cleanups
+
+Trivial cleanups in flowspace.operation : fix comment & duplicated method
+
+.. branch: test-AF_NETLINK
+
+Add a test for pre-existing AF_NETLINK support. Was part of issue #1942.
+
+.. branch: small-cleanups-misc
+
+Trivial misc cleanups: typo, whitespace, obsolete comments
+
+.. branch: cpyext-slotdefs
+.. branch: fix-missing-canraise
+.. branch: whatsnew
+
+.. branch: fix-2211
+
+Fix the cryptic exception message when attempting to use extended slicing
+in rpython. Was issue #2211.
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
@@ -89,6 +89,7 @@
 'set_code_callback' : 'interp_magic.set_code_callback',
 'save_module_content_for_future_reload':
   'interp_magic.save_module_content_for_future_reload',
+'decode_long'   : 'interp_magic.decode_long',
 }
 if sys.platform == 'win32':
 interpleveldefs['get_console_cp'] = 

[pypy-commit] pypy stmgc-c8: Next merge with default

2016-02-23 Thread Raemi
Author: Remi Meier 
Branch: stmgc-c8
Changeset: r82418:76de496c32c4
Date: 2016-02-23 10:56 +0100
http://bitbucket.org/pypy/pypy/changeset/76de496c32c4/

Log:Next merge with default

diff too long, truncating to 2000 out of 2927 lines

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -39,5 +39,5 @@
 # runs.  We cannot get their original value either:
 # http://lists.gnu.org/archive/html/help-make/2010-08/msg00106.html
 
-cffi_imports:
+cffi_imports: pypy-c
PYTHONPATH=. ./pypy-c pypy/tool/build_cffi_imports.py
diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py
--- a/lib-python/2.7/sysconfig.py
+++ b/lib-python/2.7/sysconfig.py
@@ -524,6 +524,13 @@
 import _osx_support
 _osx_support.customize_config_vars(_CONFIG_VARS)
 
+# PyPy:
+import imp
+for suffix, mode, type_ in imp.get_suffixes():
+if type_ == imp.C_EXTENSION:
+_CONFIG_VARS['SOABI'] = suffix.split('.')[1]
+break
+
 if args:
 vals = []
 for name in args:
diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py
--- a/lib_pypy/cPickle.py
+++ b/lib_pypy/cPickle.py
@@ -167,7 +167,11 @@
 try:
 key = ord(self.read(1))
 while key != STOP:
-self.dispatch[key](self)
+try:
+meth = self.dispatch[key]
+except KeyError:
+raise UnpicklingError("invalid load key, %r." % chr(key))
+meth(self)
 key = ord(self.read(1))
 except TypeError:
 if self.read(1) == '':
@@ -559,6 +563,7 @@
 
 def decode_long(data):
 r"""Decode a long from a two's complement little-endian binary string.
+This is overriden on PyPy by a RPython version that has linear complexity.
 
 >>> decode_long('')
 0L
@@ -592,6 +597,11 @@
 n -= 1L << (nbytes << 3)
 return n
 
+try:
+from __pypy__ import decode_long
+except ImportError:
+pass
+
 def load(f):
 return Unpickler(f).load()
 
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
@@ -103,3 +103,10 @@
 
 Fix the cryptic exception message when attempting to use extended slicing
 in rpython. Was issue #2211.
+
+.. branch: ec-keepalive
+
+Optimize the case where, in a new C-created thread, we keep invoking
+short-running Python callbacks.  (CFFI on CPython has a hack to achieve
+the same result.)  This can also be seen as a bug fix: previously,
+thread-local objects would be reset between two such calls.
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -9,8 +9,8 @@
 class Code(W_Root):
 """A code is a compiled version of some source code.
 Abstract base class."""
-_immutable_ = True
 hidden_applevel = False
+_immutable_fields_ = ['co_name', 'fast_natural_arity', 'hidden_applevel']
 
 # n >= 0 : arity
 # FLATPYCALL = 0x100
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -56,10 +56,12 @@
 
 class PyCode(eval.Code):
 "CPython-style code objects."
-_immutable_ = True
-_immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]",
-  "co_freevars[*]", "co_cellvars[*]",
-  "_args_as_cellvars[*]"]
+_immutable_fields_ = ["_signature", "co_argcount", "co_cellvars[*]",
+  "co_code", "co_consts_w[*]", "co_filename",
+  "co_firstlineno", "co_flags", "co_freevars[*]",
+  "co_lnotab", "co_names_w[*]", "co_nlocals",
+  "co_stacksize", "co_varnames[*]",
+  "_args_as_cellvars[*]", "w_globals?"]
 
 def __init__(self, space,  argcount, nlocals, stacksize, flags,
  code, consts, names, varnames, filename,
@@ -84,6 +86,10 @@
 self.co_name = name
 self.co_firstlineno = firstlineno
 self.co_lnotab = lnotab
+# store the first globals object that the code object is run in in
+# here. if a frame is run in that globals object, it does not need to
+# store it at all
+self.w_globals = None
 self.hidden_applevel = hidden_applevel
 self.magic = magic
 self._signature = cpython_code_signature(self)
@@ -91,6 +97,14 @@
 self._init_ready()
 self.new_code_hook()
 
+def frame_stores_global(self, w_globals):
+if self.w_globals is None:
+self.w_globals = w_globals
+return False
+if self.w_globals is w_globals:
+return False
+return True
+
 def new_code_hook(self):
 code_hook = self.space.fromcache(CodeHookCache)._code_hook
 if code_hook is 

[pypy-commit] pypy default: Kill rpython -> pypy import in a test which is skipped anyway.

2016-02-23 Thread mjacob
Author: Manuel Jacob 
Branch: 
Changeset: r82416:f3c9014fe2c7
Date: 2016-02-23 10:14 +0100
http://bitbucket.org/pypy/pypy/changeset/f3c9014fe2c7/

Log:Kill rpython -> pypy import in a test which is skipped anyway.

diff --git a/rpython/jit/backend/ppc/test/test_runner.py 
b/rpython/jit/backend/ppc/test/test_runner.py
--- a/rpython/jit/backend/ppc/test/test_runner.py
+++ b/rpython/jit/backend/ppc/test/test_runner.py
@@ -134,7 +134,7 @@
 
 def test_debugger_on(self):
 py.test.skip("XXX")
-from pypy.rlib import debug
+from rpython.rlib import debug
 
 targettoken, preambletoken = TargetToken(), TargetToken()
 loop = """
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit