[pypy-commit] pypy default: fixes for newbyteorder on flexible dtypes
Author: Brian Kearns Branch: Changeset: r69407:6928506f34e4 Date: 2014-02-25 03:22 -0500 http://bitbucket.org/pypy/pypy/changeset/6928506f34e4/ Log:fixes for newbyteorder on flexible dtypes diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -409,7 +409,9 @@ endian = newendian itemtype = self.itemtype.__class__(endian in (NPY.NATIVE, NPY.NATBYTE)) return W_Dtype(itemtype, self.num, self.kind, self.char, - self.w_box_type, byteorder=endian, elsize=self.elsize) + self.w_box_type, byteorder=endian, elsize=self.elsize, + names=self.names, fields=self.fields, + shape=self.shape, subdtype=self.subdtype) @specialize.arg(2) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -428,6 +428,20 @@ s2 = np.array(123, dtype=dt2).byteswap().tostring() assert s1 == s2 +d = np.dtype([('', 'i8', 0) +assert d.subdtype is None +#assert d.descr == [('f0', '>i8')] +#assert str(d) == "[('f0', '>i8')]" +d = np.dtype(('https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: another fix
Author: Brian Kearns Branch: Changeset: r69408:3bb2f09c6ca4 Date: 2014-02-25 03:27 -0500 http://bitbucket.org/pypy/pypy/changeset/3bb2f09c6ca4/ Log:another fix diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -408,9 +408,12 @@ elif newendian != NPY.IGNORE: endian = newendian itemtype = self.itemtype.__class__(endian in (NPY.NATIVE, NPY.NATBYTE)) +fields = self.fields +if fields is None: +fields = {} return W_Dtype(itemtype, self.num, self.kind, self.char, self.w_box_type, byteorder=endian, elsize=self.elsize, - names=self.names, fields=self.fields, + names=self.names, fields=fields, shape=self.shape, subdtype=self.subdtype) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: Copy the dictionary-like trees from "c4".
Author: Armin Rigo Branch: c7-refactor Changeset: r852:85c1e725fba0 Date: 2014-02-25 09:19 +0100 http://bitbucket.org/pypy/stmgc/changeset/85c1e725fba0/ Log:Copy the dictionary-like trees from "c4". diff --git a/c7/stm/list.c b/c7/stm/list.c --- a/c7/stm/list.c +++ b/c7/stm/list.c @@ -29,3 +29,150 @@ lst->last_allocated = nalloc - 1; return lst; } + + +// + +static void _tree_clear_node(wlog_node_t *node) +{ +memset(node, 0, sizeof(wlog_node_t)); +} + +static void tree_clear(struct tree_s *tree) +{ +if (tree->raw_current != tree->raw_start) { +_tree_clear_node(&tree->toplevel); +tree->raw_current = tree->raw_start; +} +} + +static struct tree_s *tree_create(void) +{ +return (struct tree_s *)calloc(1, sizeof(struct tree_s)); +} + +static void tree_free(struct tree_s *tree) +{ +free(tree->raw_start); +free(tree); +} + +static void _tree_compress(struct tree_s *tree) +{ + wlog_t *item; + struct tree_s tree_copy; + memset(&tree_copy, 0, sizeof(struct tree_s)); + + TREE_LOOP_FORWARD(*tree, item) +{ + tree_insert(&tree_copy, item->addr, item->val); + +} TREE_LOOP_END; + + free(tree->raw_start); + *tree = tree_copy; +} + +static wlog_t *_tree_find(char *entry, uintptr_t addr) +{ +uintptr_t key = addr; +while (((long)entry) & 1) { +/* points to a further level */ +key >>= TREE_BITS; +entry = *(char **)((entry - 1) + (key & TREE_MASK)); +} +return (wlog_t *)entry; /* may be NULL */ +} + +static void _tree_grow(struct tree_s *tree, long extra) +{ +struct tree_s newtree; +wlog_t *item; +long alloc = tree->raw_end - tree->raw_start; +long newalloc = (alloc + extra + (alloc >> 2) + 31) & ~15; +//fprintf(stderr, "growth: %ld\n", newalloc); +char *newitems = malloc(newalloc); +if (newitems == NULL) { +stm_fatalerror("out of memory!\n"); /* XXX */ +} +newtree.raw_start = newitems; +newtree.raw_current = newitems; +newtree.raw_end = newitems + newalloc; +_tree_clear_node(&newtree.toplevel); +TREE_LOOP_FORWARD(*tree, item) +{ +tree_insert(&newtree, item->addr, item->val); +} TREE_LOOP_END; +free(tree->raw_start); +*tree = newtree; +} + +static char *_tree_grab(struct tree_s *tree, long size) +{ +char *result; +result = tree->raw_current; +tree->raw_current += size; +if (tree->raw_current > tree->raw_end) { +_tree_grow(tree, size); +return NULL; +} +return result; +} + +static void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val) +{ + retry:; +wlog_t *wlog; +uintptr_t key = addr; +int shift = 0; +char *p = (char *)(tree->toplevel.items); +char *entry; +while (1) { +p += (key >> shift) & TREE_MASK; +shift += TREE_BITS; +entry = *(char **)p; +if (entry == NULL) +break; +else if (((long)entry) & 1) { +/* points to a further level */ +p = entry - 1; +} +else { +wlog_t *wlog1 = (wlog_t *)entry; +if (wlog1->addr == 0) { +/* reuse the deleted entry and that's it */ +wlog1->addr = addr; +wlog1->val = val; +return; +} +/* the key must not already be present */ +assert(wlog1->addr != addr); +/* collision: there is already a different wlog here */ +wlog_node_t *node = (wlog_node_t *) +_tree_grab(tree, sizeof(wlog_node_t)); +if (node == NULL) goto retry; +_tree_clear_node(node); +uintptr_t key1 = wlog1->addr; +char *p1 = (char *)(node->items); +*(wlog_t **)(p1 + ((key1 >> shift) & TREE_MASK)) = wlog1; +*(char **)p = ((char *)node) + 1; +p = p1; +} +} +wlog = (wlog_t *)_tree_grab(tree, sizeof(wlog_t)); +if (wlog == NULL) goto retry; +wlog->addr = addr; +wlog->val = val; +*(char **)p = (char *)wlog; +} + +static bool tree_delete_item(struct tree_s *tree, uintptr_t addr) +{ +wlog_t *entry; +TREE_FIND(*tree, addr, entry, goto missing); +entry->addr = 0; +return true; + + missing: +return false; +} diff --git a/c7/stm/list.h b/c7/stm/list.h --- a/c7/stm/list.h +++ b/c7/stm/list.h @@ -1,5 +1,7 @@ #include +// + struct list_s { uintptr_t count; uintptr_t last_allocated; @@ -65,3 +67,121 @@ CODE; \ } \ } while (0) + +// + +/* The tree_xx functions are, like the name hints, implemented as a tree, + supporting very high performance in TREE_FIND in the common case where + there are no or few elem
[pypy-commit] stmgc c7-refactor: Use the trees to implement young_outside_nursery, step 1.
Author: Armin Rigo Branch: c7-refactor Changeset: r853:9fb1364ed14f Date: 2014-02-25 09:38 +0100 http://bitbucket.org/pypy/stmgc/changeset/9fb1364ed14f/ Log:Use the trees to implement young_outside_nursery, step 1. diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -179,6 +179,7 @@ } assert(list_is_empty(STM_PSEGMENT->modified_old_objects)); +assert(tree_is_cleared(STM_PSEGMENT->young_outside_nursery)); assert(STM_PSEGMENT->objects_pointing_to_nursery == NULL); assert(STM_PSEGMENT->large_overflow_objects == NULL); diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -81,6 +81,11 @@ current transaction spanned a minor collection. */ struct list_s *large_overflow_objects; +/* List of all young objects outside the nursery ("young" in the + sense that they should be in the nursery, but were too big for + that). */ +struct tree_s *young_outside_nursery; + /* Start time: to know approximately for how long a transaction has been running, in contention management */ uint64_t start_time; diff --git a/c7/stm/list.h b/c7/stm/list.h --- a/c7/stm/list.h +++ b/c7/stm/list.h @@ -105,8 +105,8 @@ static void tree_clear(struct tree_s *tree); //static inline void tree_delete_not_used_any_more(struct tree_s *tree)... -static inline bool tree_any_entry(struct tree_s *tree) { -return tree->raw_current != tree->raw_start; +static inline bool tree_is_cleared(struct tree_s *tree) { +return tree->raw_current == tree->raw_start; } #define _TREE_LOOP(tree, item, INITIAL, _PLUS_) \ @@ -177,7 +177,8 @@ static wlog_t *_tree_find(char *entry, uintptr_t addr); static void _tree_compress(struct tree_s *tree) __attribute__((unused)); static void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val); -static bool tree_delete_item(struct tree_s *tree, uintptr_t addr); +static bool tree_delete_item(struct tree_s *tree, uintptr_t addr) + __attribute__((unused)); static inline bool tree_contains(struct tree_s *tree, uintptr_t addr) { diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c --- a/c7/stm/nursery.c +++ b/c7/stm/nursery.c @@ -182,6 +182,19 @@ memset(realnursery, 0, size); STM_SEGMENT->nursery_current = (stm_char *)_stm_nursery_start; + +/* free any object left from 'young_outside_nursery' */ +if (!tree_is_cleared(STM_PSEGMENT->young_outside_nursery)) { +mutex_pages_lock(); + +wlog_t *item; +TREE_LOOP_FORWARD(*STM_PSEGMENT->young_outside_nursery, item) { +_stm_large_free(stm_object_pages + item->addr); +} TREE_LOOP_END; + +tree_clear(STM_PSEGMENT->young_outside_nursery); +mutex_pages_unlock(); +} } static void minor_collection(bool commit) @@ -268,7 +281,14 @@ object_t *_stm_allocate_external(ssize_t size_rounded_up) { -abort();//... +/* XXX force a minor/major collection if needed */ + +char *result = allocate_outside_nursery_large(size_rounded_up); +memset(result, 0, size_rounded_up); + +object_t *o = (object_t *)(result - stm_object_pages); +tree_insert(STM_PSEGMENT->young_outside_nursery, (intptr_t)o, 0); +return o; } #ifdef STM_TESTS diff --git a/c7/stm/setup.c b/c7/stm/setup.c --- a/c7/stm/setup.c +++ b/c7/stm/setup.c @@ -56,6 +56,7 @@ pr->objects_pointing_to_nursery = NULL; pr->large_overflow_objects = NULL; pr->modified_old_objects = list_create(); +pr->young_outside_nursery = tree_create(); pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * (i + 1); highest_overflow_number = pr->overflow_number; } @@ -88,6 +89,7 @@ assert(pr->objects_pointing_to_nursery == NULL); assert(pr->large_overflow_objects == NULL); list_free(pr->modified_old_objects); +tree_free(pr->young_outside_nursery); } munmap(stm_object_pages, TOTAL_MEMORY); diff --git a/c7/test/test_list.py b/c7/test/test_list.py --- a/c7/test/test_list.py +++ b/c7/test/test_list.py @@ -1,3 +1,4 @@ +import random import cffi from common import parent_dir @@ -9,9 +10,11 @@ struct tree_s *tree_create(void); void tree_free(struct tree_s *tree); void tree_clear(struct tree_s *tree); +bool tree_is_cleared(struct tree_s *tree); bool tree_contains(struct tree_s *tree, uintptr_t addr); void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val); bool tree_delete_item(struct tree_s *tree, uintptr_t addr); +int test_tree_walk(struct tree_s *tree, uintptr_t addrs[]); """) lib = ffi.verify(''' @@ -27,6 +30,23 @@ #define _STM_CORE_H_ #include "stm/list.c" + +int test_tree_walk(struct tree_s *tree, uintptr_t addrs[]) +{ +int result = 0; +wlog_t *item; +TREE_LOOP_FORWARD(*tree, item) { +addrs[result++] = item->addr; +} TREE_LOOP_END; +int i = result; +TREE_LOOP_BACKWARD(*tree, item) { +assert(i
[pypy-commit] stmgc c7-refactor: Actually implement surviving young_outside_nursery
Author: Armin Rigo Branch: c7-refactor Changeset: r854:4302246a0ad0 Date: 2014-02-25 09:50 +0100 http://bitbucket.org/pypy/stmgc/changeset/4302246a0ad0/ Log:Actually implement surviving young_outside_nursery diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -12,7 +12,7 @@ void _stm_write_slowpath(object_t *obj) { assert(_running_transaction()); -assert(!_is_in_nursery(obj)); +assert(!_is_young(obj)); /* is this an object from the same transaction, outside the nursery? */ if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) == @@ -225,7 +225,7 @@ static void synchronize_overflow_object_now(object_t *obj) { -assert(!_is_in_nursery(obj)); +assert(!_is_young(obj)); assert((obj->stm_flags & GCFLAG_SMALL_UNIFORM) == 0); char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c --- a/c7/stm/nursery.c +++ b/c7/stm/nursery.c @@ -42,6 +42,12 @@ return (uintptr_t)obj < NURSERY_END; } +static inline bool _is_young(object_t *obj) +{ +return (_is_in_nursery(obj) || +tree_contains(STM_PSEGMENT->young_outside_nursery, (uintptr_t)obj)); +} + bool _stm_in_nursery(object_t *obj) { return _is_in_nursery(obj); @@ -54,6 +60,19 @@ #define FLAG_SYNC_LARGE_NOW 0x01 +static void minor_young_outside_nursery(object_t *obj) +{ +tree_delete_item(STM_PSEGMENT->young_outside_nursery, (uintptr_t)obj); + +uintptr_t nobj_sync_now = (uintptr_t)obj; +if (STM_PSEGMENT->minor_collect_will_commit_now) +nobj_sync_now |= FLAG_SYNC_LARGE_NOW; +else +LIST_APPEND(STM_PSEGMENT->large_overflow_objects, obj); + +LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, nobj_sync_now); +} + static void minor_trace_if_young(object_t **pobj) { /* takes a normal pointer to a thread-local pointer to an object */ @@ -61,8 +80,13 @@ if (obj == NULL) return; assert((uintptr_t)obj < NB_PAGES * 4096UL); -if (!_is_in_nursery(obj)) -return; +if (!_is_in_nursery(obj)) { +if (UNLIKELY(tree_contains(STM_PSEGMENT->young_outside_nursery, + (uintptr_t)obj))) { +minor_young_outside_nursery(obj); +} +return; /* else old object, nothing to do */ +} /* If the object was already seen here, its first word was set to GCWORD_MOVED. In that case, the forwarding location, i.e. @@ -133,7 +157,7 @@ static inline void _collect_now(object_t *obj) { -assert(!_is_in_nursery(obj)); +assert(!_is_young(obj)); /* We must not have GCFLAG_WRITE_BARRIER so far. Add it now. */ assert(!(obj->stm_flags & GCFLAG_WRITE_BARRIER)); diff --git a/c7/test/test_nursery.py b/c7/test/test_nursery.py --- a/c7/test/test_nursery.py +++ b/c7/test/test_nursery.py @@ -81,7 +81,7 @@ assert old assert young -def test_larger_than_limit_for_nursery(self): +def test_larger_than_limit_for_nursery_die(self): obj_size = lib._STM_FAST_ALLOC + 16 self.start_transaction() @@ -93,6 +93,28 @@ seen.add(new) assert len(seen) < 5 # addresses are reused +def test_larger_than_limit_for_nursery_dont_die(self): +obj_nrefs = (lib._STM_FAST_ALLOC + 16) // 8 + +self.start_transaction() +lp1 = ffi.cast("object_t *", 0) +seen = set() +for i in range(100): +self.push_root(lp1) +stm_minor_collect() +lp1 = self.pop_root() +new = stm_allocate_refs(obj_nrefs) +assert not is_in_nursery(new) +seen.add(new) +stm_set_ref(new, i, lp1) +lp1 = new +assert len(seen) == 100 # addresses are not reused + +for i in reversed(range(100)): +assert lp1 +lp1 = stm_get_ref(lp1, i) +assert not lp1 + def test_reset_partial_alloc_pages(self): py.test.skip("a would-be-nice feature, but not actually needed: " "the next major GC will take care of it") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Replace @jit.elidable with @specialize.memo
Author: Maciej Fijalkowski Branch: Changeset: r69409:3dbefef835d5 Date: 2014-02-25 10:51 +0200 http://bitbucket.org/pypy/pypy/changeset/3dbefef835d5/ Log:Replace @jit.elidable with @specialize.memo diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,7 +16,7 @@ from pypy.interpreter.mixedmodule import MixedModule from rpython.rtyper.lltypesystem import lltype from rpython.rlib.rstring import StringBuilder -from rpython.rlib import jit +from rpython.rlib.objectmodel import specialize from pypy.module.micronumpy import constants as NPY @@ -34,7 +34,7 @@ def new_dtype_getter(num): -@jit.elidable +@specialize.memo() def _get_dtype(space): from pypy.module.micronumpy.interp_dtype import get_dtype_cache return get_dtype_cache(space).dtypes_by_num[num] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix a char dtype case
Author: Brian Kearns Branch: Changeset: r69410:89a5865820d1 Date: 2014-02-25 03:52 -0500 http://bitbucket.org/pypy/pypy/changeset/89a5865820d1/ Log:fix a char dtype case diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -587,10 +587,8 @@ except ValueError: raise oefmt(space.w_TypeError, "data type not understood") if char == NPY.CHARLTR: -char = NPY.STRINGLTR -size = 1 - -if char == NPY.STRINGLTR: +return new_string_dtype(space, 1, NPY.CHARLTR) +elif char == NPY.STRINGLTR: return new_string_dtype(space, size) elif char == NPY.UNICODELTR: return new_unicode_dtype(space, size) @@ -599,13 +597,13 @@ assert False -def new_string_dtype(space, size): +def new_string_dtype(space, size, char=NPY.STRINGLTR): return W_Dtype( types.StringType(), elsize=size, num=NPY.STRING, kind=NPY.STRINGLTR, -char=NPY.STRINGLTR, +char=char, w_box_type=space.gettypefor(interp_boxes.W_StringBox), ) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -891,6 +891,11 @@ assert dtype('void').byteorder == '|' assert dtype((int, 2)).byteorder == '|' assert dtype(np.generic).str == '|V0' +d = dtype(np.character) +assert d.num == 18 +assert d.char == 'S' +assert d.kind == 'S' +assert d.str == '|S0' def test_dtype_str(self): from numpypy import dtype @@ -1055,9 +1060,15 @@ assert isinstance(u, unicode) def test_character_dtype(self): +import numpy as np from numpypy import array, character x = array([["A", "B"], ["C", "D"]], character) assert (x == [["A", "B"], ["C", "D"]]).all() +d = np.dtype('c') +assert d.num == 18 +assert d.char == 'c' +assert d.kind == 'S' +assert d.str == '|S1' class AppTestRecordDtypes(BaseNumpyAppTest): spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"]) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix array init with char dtype
Author: Brian Kearns Branch: Changeset: r69411:0f6a27d08000 Date: 2014-02-25 04:05 -0500 http://bitbucket.org/pypy/pypy/changeset/0f6a27d08000/ Log:fix array init with char dtype diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -1448,9 +1448,10 @@ # scalars and strings w/o __array__ method isstr = space.isinstance_w(w_object, space.w_str) if not issequence_w(space, w_object) or isstr: -if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): -dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) -return W_NDimArray.new_scalar(space, dtype, w_object) +if dtype is None or dtype.char != NPY.CHARLTR: +if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): +dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) +return W_NDimArray.new_scalar(space, dtype, w_object) if space.is_none(w_order): order = 'C' diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1697,16 +1697,12 @@ assert exc.value[0] == "data-type must not be 0-sized" assert a.view('S4') == '\x03' a = array('abc1', dtype='c') -import sys -if '__pypy__' in sys.builtin_module_names: -raises(ValueError, a.view, 'S4') -raises(ValueError, a.view, [('a', 'i2'), ('b', 'i2')]) -else: -assert a.view('S4') == 'abc1' -b = a.view([('a', 'i2'), ('b', 'i2')]) -assert b.shape == (1,) -assert b[0][0] == 25185 -assert b[0][1] == 12643 +assert (a == ['a', 'b', 'c', '1']).all() +assert a.view('S4') == 'abc1' +b = a.view([('a', 'i2'), ('b', 'i2')]) +assert b.shape == (1,) +assert b[0][0] == 25185 +assert b[0][1] == 12643 a = array([(1, 2)], dtype=[('a', 'int64'), ('b', 'int64')])[0] assert a.shape == () assert a.view('S16') == '\x01' + '\x00' * 7 + '\x02' ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: Refactoring and small fix
Author: Armin Rigo Branch: c7-refactor Changeset: r855:76937b4f5d6e Date: 2014-02-25 10:05 +0100 http://bitbucket.org/pypy/stmgc/changeset/76937b4f5d6e/ Log:Refactoring and small fix diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c --- a/c7/stm/nursery.c +++ b/c7/stm/nursery.c @@ -60,86 +60,88 @@ #define FLAG_SYNC_LARGE_NOW 0x01 -static void minor_young_outside_nursery(object_t *obj) +static uintptr_t minor_record_large_overflow_object(object_t *nobj) { -tree_delete_item(STM_PSEGMENT->young_outside_nursery, (uintptr_t)obj); - -uintptr_t nobj_sync_now = (uintptr_t)obj; +uintptr_t nobj_sync_now = (uintptr_t)nobj; if (STM_PSEGMENT->minor_collect_will_commit_now) nobj_sync_now |= FLAG_SYNC_LARGE_NOW; else -LIST_APPEND(STM_PSEGMENT->large_overflow_objects, obj); - -LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, nobj_sync_now); +LIST_APPEND(STM_PSEGMENT->large_overflow_objects, nobj); +return nobj_sync_now; } static void minor_trace_if_young(object_t **pobj) { /* takes a normal pointer to a thread-local pointer to an object */ object_t *obj = *pobj; +object_t *nobj; +uintptr_t nobj_sync_now; + if (obj == NULL) return; assert((uintptr_t)obj < NB_PAGES * 4096UL); -if (!_is_in_nursery(obj)) { -if (UNLIKELY(tree_contains(STM_PSEGMENT->young_outside_nursery, - (uintptr_t)obj))) { -minor_young_outside_nursery(obj); + +if (_is_in_nursery(obj)) { +/* If the object was already seen here, its first word was set + to GCWORD_MOVED. In that case, the forwarding location, i.e. + where the object moved to, is stored in the second word in 'obj'. */ +object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)obj; + +if (pforwarded_array[0] == GCWORD_MOVED) { +*pobj = pforwarded_array[1];/* already moved */ +return; } -return; /* else old object, nothing to do */ + +/* We need to make a copy of this object. It goes either in + a largemalloc.c-managed area, or if it's small enough, in + one of the small uniform pages from gcpage.c. +*/ +char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); +size_t size = stmcb_size_rounded_up((struct object_s *)realobj); + +if (1 /*size >= GC_MEDIUM_REQUEST*/) { + +/* case 1: object is not small enough. + Ask gcpage.c for an allocation via largemalloc. */ +char *allocated = allocate_outside_nursery_large(size); +nobj = (object_t *)(allocated - stm_object_pages); + +/* Copy the object */ +char *realnobj = REAL_ADDRESS(STM_SEGMENT->segment_base, nobj); +memcpy(realnobj, realobj, size); + +nobj_sync_now = minor_record_large_overflow_object(nobj); +} +else { +/* case "small enough" */ +abort(); //... +} + +/* Done copying the object. */ +//dprintf(("\t\t\t\t\t%p -> %p\n", obj, nobj)); +pforwarded_array[0] = GCWORD_MOVED; +pforwarded_array[1] = nobj; +*pobj = nobj; } -/* If the object was already seen here, its first word was set - to GCWORD_MOVED. In that case, the forwarding location, i.e. - where the object moved to, is stored in the second word in 'obj'. */ -object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)obj; +else { +/* The object was not in the nursery at all */ +if (LIKELY(!tree_contains(STM_PSEGMENT->young_outside_nursery, + (uintptr_t)obj))) +return; /* common case: it was an old object, nothing to do */ -if (pforwarded_array[0] == GCWORD_MOVED) { -*pobj = pforwarded_array[1];/* already moved */ -return; +/* a young object outside the nursery */ +nobj = obj; +tree_delete_item(STM_PSEGMENT->young_outside_nursery, (uintptr_t)nobj); +nobj_sync_now = minor_record_large_overflow_object(nobj); } -/* We need to make a copy of this object. It goes either in - a largemalloc.c-managed area, or if it's small enough, in - one of the small uniform pages from gcpage.c. -*/ -char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); -size_t size = stmcb_size_rounded_up((struct object_s *)realobj); -object_t *nobj; -uintptr_t nobj_sync_now; - -if (1 /*size >= GC_MEDIUM_REQUEST*/) { - -/* case 1: object is not small enough. - Ask gcpage.c for an allocation via largemalloc. */ -char *allocated = allocate_outside_nursery_large(size); -nobj = (object_t *)(allocated - stm_object_pages); -nobj_sync_now = (uintptr_t)nobj; - -/* Copy the object */ -char *realnobj = REAL_ADDRESS(STM_SEGMENT->segment_base, nobj); -me
[pypy-commit] stmgc c7-refactor: In trees, the NULL key is reserved
Author: Armin Rigo Branch: c7-refactor Changeset: r856:e47cc9d404c2 Date: 2014-02-25 10:07 +0100 http://bitbucket.org/pypy/stmgc/changeset/e47cc9d404c2/ Log:In trees, the NULL key is reserved diff --git a/c7/stm/list.c b/c7/stm/list.c --- a/c7/stm/list.c +++ b/c7/stm/list.c @@ -121,6 +121,7 @@ static void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val) { +assert(addr != 0);/* the NULL key is reserved */ retry:; wlog_t *wlog; uintptr_t key = addr; ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Baaah. _py3k_acquire() will raise OverflowError. Work around.
Author: Armin Rigo Branch: Changeset: r69412:570e6baf64ae Date: 2014-02-25 10:19 +0100 http://bitbucket.org/pypy/pypy/changeset/570e6baf64ae/ Log:Baaah. _py3k_acquire() will raise OverflowError. Work around. diff --git a/lib-python/2.7/threading.py b/lib-python/2.7/threading.py --- a/lib-python/2.7/threading.py +++ b/lib-python/2.7/threading.py @@ -246,7 +246,14 @@ else: # PyPy patch: use _py3k_acquire() if timeout > 0: -gotit = waiter._py3k_acquire(True, timeout) +try: +gotit = waiter._py3k_acquire(True, timeout) +except OverflowError: +# bah, in Python 3, acquire(True, timeout) raises +# OverflowError if the timeout is too huge. For +# forward-compatibility reasons we do the same. +waiter.acquire() +gotit = True else: gotit = waiter.acquire(False) if not gotit: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: add very large objects
Author: Remi Meier Branch: c7-refactor Changeset: r857:d3ae1ec8e5b4 Date: 2014-02-25 11:17 +0100 http://bitbucket.org/pypy/stmgc/changeset/d3ae1ec8e5b4/ Log:add very large objects diff --git a/c7/test/test_random.py b/c7/test/test_random.py --- a/c7/test/test_random.py +++ b/c7/test/test_random.py @@ -353,6 +353,7 @@ size = global_state.rnd.choice([ "16", str(4096+16), +str(80*1024+16), #"SOME_MEDIUM_SIZE+16", #"SOME_LARGE_SIZE+16", ]) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: more informative error when refusing to create dtypes
Author: Brian Kearns Branch: Changeset: r69413:9aaa71abdd13 Date: 2014-02-25 04:45 -0500 http://bitbucket.org/pypy/pypy/changeset/9aaa71abdd13/ Log:more informative error when refusing to create dtypes diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -532,7 +532,8 @@ if w_dtype is dtype.w_box_type: return dtype if space.isinstance_w(w_dtype, space.w_type): -raise oefmt(space.w_NotImplementedError, "object dtype not implemented") +raise oefmt(space.w_NotImplementedError, +"cannot create dtype with type '%N'", w_dtype) raise oefmt(space.w_TypeError, "data type not understood") W_Dtype.typedef = TypeDef("dtype", diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -452,7 +452,7 @@ assert np.dtype(o).str == '|O8' else: exc = raises(NotImplementedError, "np.dtype(o)") -assert exc.value[0] == 'object dtype not implemented' +assert exc.value[0] == "cannot create dtype with type '%s'" % o.__name__ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: Fix: memset the right segment
Author: Armin Rigo Branch: c7-refactor Changeset: r858:fb13763ca5b2 Date: 2014-02-25 11:23 +0100 http://bitbucket.org/pypy/stmgc/changeset/fb13763ca5b2/ Log:Fix: memset the right segment diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c --- a/c7/stm/nursery.c +++ b/c7/stm/nursery.c @@ -310,10 +310,10 @@ /* XXX force a minor/major collection if needed */ char *result = allocate_outside_nursery_large(size_rounded_up); -memset(result, 0, size_rounded_up); - object_t *o = (object_t *)(result - stm_object_pages); tree_insert(STM_PSEGMENT->young_outside_nursery, (intptr_t)o, 0); + +memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up); return o; } ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Move the partial lib_pypy/disassembler.py to rpython/tool/.
Author: Armin Rigo Branch: Changeset: r69414:6749a8734e6c Date: 2014-02-25 12:17 +0100 http://bitbucket.org/pypy/pypy/changeset/6749a8734e6c/ Log:Move the partial lib_pypy/disassembler.py to rpython/tool/. Move pypy/tool/jitlogparser to rpython/root/. diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -6,8 +6,9 @@ from _pytest.assertion import newinterpret except ImportError: # e.g. Python 2.5 newinterpret = None -from pypy.tool.jitlogparser.parser import SimpleParser, Function, TraceForOpcode -from pypy.tool.jitlogparser.storage import LoopStorage +from rpython.tool.jitlogparser.parser import (SimpleParser, Function, + TraceForOpcode) +from rpython.tool.jitlogparser.storage import LoopStorage def find_ids_range(code): diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -3,7 +3,7 @@ import types import subprocess import py -from lib_pypy import disassembler +from rpython.tool import disassembler from rpython.tool.udir import udir from rpython.tool import logparser from rpython.jit.tool.jitoutput import parse_prof @@ -129,7 +129,7 @@ class TestOpMatcher_(object): def match(self, src1, src2, **kwds): -from pypy.tool.jitlogparser.parser import SimpleParser +from rpython.tool.jitlogparser.parser import SimpleParser loop = SimpleParser.parse_from_input(src1) matcher = OpMatcher(loop.operations) try: diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py --- a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py +++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py @@ -4,7 +4,7 @@ from rpython.tool.logparser import extract_category from rpython.jit.backend.tool.viewcode import ObjdumpNotFound -from pypy.tool.jitlogparser.parser import (import_log, parse_log_counts, +from rpython.tool.jitlogparser.parser import (import_log, parse_log_counts, mangle_descr) from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC diff --git a/lib_pypy/disassembler.py b/rpython/tool/disassembler.py rename from lib_pypy/disassembler.py rename to rpython/tool/disassembler.py diff --git a/pypy/tool/jitlogparser/__init__.py b/rpython/tool/jitlogparser/__init__.py rename from pypy/tool/jitlogparser/__init__.py rename to rpython/tool/jitlogparser/__init__.py diff --git a/pypy/tool/jitlogparser/module_finder.py b/rpython/tool/jitlogparser/module_finder.py rename from pypy/tool/jitlogparser/module_finder.py rename to rpython/tool/jitlogparser/module_finder.py diff --git a/pypy/tool/jitlogparser/parser.py b/rpython/tool/jitlogparser/parser.py rename from pypy/tool/jitlogparser/parser.py rename to rpython/tool/jitlogparser/parser.py diff --git a/pypy/tool/jitlogparser/storage.py b/rpython/tool/jitlogparser/storage.py rename from pypy/tool/jitlogparser/storage.py rename to rpython/tool/jitlogparser/storage.py --- a/pypy/tool/jitlogparser/storage.py +++ b/rpython/tool/jitlogparser/storage.py @@ -5,8 +5,8 @@ import py import os -from lib_pypy.disassembler import dis -from pypy.tool.jitlogparser.module_finder import gather_all_code_objs +from rpython.tool.disassembler import dis +from rpython.tool.jitlogparser.module_finder import gather_all_code_objs class LoopStorage(object): def __init__(self, extrapath=None): diff --git a/pypy/tool/jitlogparser/test/__init__.py b/rpython/tool/jitlogparser/test/__init__.py rename from pypy/tool/jitlogparser/test/__init__.py rename to rpython/tool/jitlogparser/test/__init__.py diff --git a/pypy/tool/jitlogparser/test/logtest.log b/rpython/tool/jitlogparser/test/logtest.log rename from pypy/tool/jitlogparser/test/logtest.log rename to rpython/tool/jitlogparser/test/logtest.log diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/rpython/tool/jitlogparser/test/logtest2.log rename from pypy/tool/jitlogparser/test/logtest2.log rename to rpython/tool/jitlogparser/test/logtest2.log diff --git a/pypy/tool/jitlogparser/test/test_modulefinder.py b/rpython/tool/jitlogparser/test/test_modulefinder.py rename from pypy/tool/jitlogparser/test/test_modulefinder.py rename to rpython/tool/jitlogparser/test/test_modulefinder.py --- a/pypy/tool/jitlogparser/test/test_modulefinder.py +++ b/rpython/tool/jitlogparser/test/test_modulefinder.py @@ -1,5 +1,5 @@ import py -from pypy.tool.jitlogparser.module_finder import gather_all_code_objs +from rpython.tool.jitlogparser.module_finder import gather_all_code_objs import re, sys def setup_module(mod): diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/rpython/tool/jitlogparser/test/test_parser.py renam
[pypy-commit] jitviewer default: Import everything needed from 'rpython', not from 'pypy'.
Author: Armin Rigo Branch: Changeset: r255:41c224f97da8 Date: 2014-02-25 12:19 +0100 http://bitbucket.org/pypy/jitviewer/changeset/41c224f97da8/ Log:Import everything needed from 'rpython', not from 'pypy'. diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -29,12 +29,12 @@ import argparse try: -import pypy +import rpython except ImportError: import __pypy__ sys.path.append(os.path.join(__pypy__.__file__, '..', '..', '..')) try: -import pypy +import rpython except ImportError: failout('Could not import pypy module, make sure to ' 'add the pypy module to PYTHONPATH') @@ -47,13 +47,21 @@ import inspect import threading import time + try: from rpython.tool.logparser import extract_category except ImportError: from pypy.tool.logparser import extract_category -from pypy.tool.jitlogparser.storage import LoopStorage -from pypy.tool.jitlogparser.parser import adjust_bridges, import_log,\ - parse_log_counts +try: +from rpython.tool.jitlogparser.storage import LoopStorage +except ImportError: +from pypy.tool.jitlogparser.storage import LoopStorage +try: +from rpython.tool.jitlogparser.parser import adjust_bridges, import_log,\ + parse_log_counts +except ImportError: +from pypy.tool.jitlogparser.parser import adjust_bridges, import_log,\ + parse_log_counts # from _jitviewer.parser import ParserWithHtmlRepr, FunctionHtml from _jitviewer.display import CodeRepr, CodeReprNoFile diff --git a/_jitviewer/parser.py b/_jitviewer/parser.py --- a/_jitviewer/parser.py +++ b/_jitviewer/parser.py @@ -1,6 +1,9 @@ import re import cgi -from pypy.tool.jitlogparser import parser +try: +from rpython.tool.jitlogparser import parser +except ImportError: +from pypy.tool.jitlogparser import parser def cssclass(cls, s, **kwds): cls = re.sub("[^\w]", "_", cls) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: More precise crash, better explanation
Author: Armin Rigo Branch: Changeset: r69416:8ccaadbf0ecf Date: 2014-02-25 12:58 +0100 http://bitbucket.org/pypy/pypy/changeset/8ccaadbf0ecf/ Log:More precise crash, better explanation diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -240,13 +240,19 @@ extraeffect = EffectInfo.EF_CAN_RAISE else: extraeffect = EffectInfo.EF_CANNOT_RAISE -else: -assert not loopinvariant, ( +# +# check that the result is really as expected +if loopinvariant: +assert extraeffect == EffectInfo.EF_LOOPINVARIANT, ( "in operation %r: this calls a _jit_loop_invariant_ function," -" but it can have random effects") -assert not elidable, ( +" but this contradicts other sources (e.g. it can have random" +" effects)" % (op,)) +if elidable: +assert extraeffect in (EffectInfo.EF_ELIDABLE_CANNOT_RAISE, + EffectInfo.EF_ELIDABLE_CAN_RAISE), ( "in operation %r: this calls an _elidable_function_," -" but it can have random effects") +" but this contradicts other sources (e.g. it can have random" +" effects)" % (op,)) # effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op, self.seen), self.cpu, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Test and fix: the _nowrapper C functions couldn't be elided before.
Author: Armin Rigo Branch: Changeset: r69417:3c477e9543db Date: 2014-02-25 13:16 +0100 http://bitbucket.org/pypy/pypy/changeset/3c477e9543db/ Log:Test and fix: the _nowrapper C functions couldn't be elided before. diff --git a/rpython/jit/codewriter/test/test_call.py b/rpython/jit/codewriter/test/test_call.py --- a/rpython/jit/codewriter/test/test_call.py +++ b/rpython/jit/codewriter/test/test_call.py @@ -248,3 +248,26 @@ op = block.operations[-1] call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() + +def test_no_random_effects_for_rotateLeft(): +from rpython.jit.backend.llgraph.runner import LLGraphCPU +from rpython.rlib.rarithmetic import r_uint + +if r_uint.BITS == 32: +py.test.skip("64-bit only") + +from rpython.rlib.rmd5 import _rotateLeft +def f(n, m): +return _rotateLeft(r_uint(n), m) + +rtyper = support.annotate(f, [7, 9]) +jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) +cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) +res = cc.find_all_graphs(FakePolicy()) + +[f_graph] = [x for x in res if x.func is f] +[block, _] = list(f_graph.iterblocks()) +op = block.operations[-1] +call_descr = cc.getcalldescr(op) +assert not call_descr.extrainfo.has_random_effects() +assert call_descr.extrainfo.check_is_elidable() diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -116,12 +116,14 @@ # default case: # invoke the around-handlers only for "not too small" external calls; # sandboxsafe is a hint for "too-small-ness" (e.g. math functions). -invoke_around_handlers = not sandboxsafe +# Also, _nowrapper functions cannot release the GIL, by default. +invoke_around_handlers = not sandboxsafe and not _nowrapper if random_effects_on_gcobjs not in (False, True): random_effects_on_gcobjs = ( invoke_around_handlers or # because it can release the GIL has_callback) # because the callback can do it +assert not (elidable_function and random_effects_on_gcobjs) funcptr = lltype.functionptr(ext_type, name, external='C', compilation_info=compilation_info, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Complain for now when a function is both elidable (or loopinvariant),
Author: Armin Rigo Branch: Changeset: r69415:6e5573ced07d Date: 2014-02-25 12:37 +0100 http://bitbucket.org/pypy/pypy/changeset/6e5573ced07d/ Log:Complain for now when a function is both elidable (or loopinvariant), and can have random effects. diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -240,6 +240,13 @@ extraeffect = EffectInfo.EF_CAN_RAISE else: extraeffect = EffectInfo.EF_CANNOT_RAISE +else: +assert not loopinvariant, ( +"in operation %r: this calls a _jit_loop_invariant_ function," +" but it can have random effects") +assert not elidable, ( +"in operation %r: this calls an _elidable_function_," +" but it can have random effects") # effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op, self.seen), self.cpu, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Replace the crash with a warning for now
Author: Armin Rigo Branch: Changeset: r69418:040f3ac28afb Date: 2014-02-25 14:02 +0100 http://bitbucket.org/pypy/pypy/changeset/040f3ac28afb/ Log:Replace the crash with a warning for now diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -243,13 +243,15 @@ # # check that the result is really as expected if loopinvariant: -assert extraeffect == EffectInfo.EF_LOOPINVARIANT, ( +if extraeffect != EffectInfo.EF_LOOPINVARIANT: +from rpython.jit.codewriter.policy import log; log.WARNING( "in operation %r: this calls a _jit_loop_invariant_ function," " but this contradicts other sources (e.g. it can have random" " effects)" % (op,)) if elidable: -assert extraeffect in (EffectInfo.EF_ELIDABLE_CANNOT_RAISE, - EffectInfo.EF_ELIDABLE_CAN_RAISE), ( +if extraeffect not in (EffectInfo.EF_ELIDABLE_CANNOT_RAISE, + EffectInfo.EF_ELIDABLE_CAN_RAISE): +from rpython.jit.codewriter.policy import log; log.WARNING( "in operation %r: this calls an _elidable_function_," " but this contradicts other sources (e.g. it can have random" " effects)" % (op,)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Write down a good idea found in module/_rawffi/alt/interp_ffitype.py.
Author: Armin Rigo Branch: Changeset: r69419:1a6a0914772c Date: 2014-02-25 14:16 +0100 http://bitbucket.org/pypy/pypy/changeset/1a6a0914772c/ Log:Write down a good idea found in module/_rawffi/alt/interp_ffitype.py. diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -14,6 +14,8 @@ _immutable_fields_ = ['size?', 'name', 'name_position'] # note that 'size' is not strictly immutable, because it can change # from -1 to the real value in the W_CTypeStruct subclass. +# XXX this could be improved with an elidable method get_size() +# that raises in case it's still -1... cast_anything = False is_primitive_integer = False ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix for @jit.elidable. Previously, it would elidably return None, even
Author: Armin Rigo Branch: Changeset: r69420:35e7f867cc40 Date: 2014-02-25 14:23 +0100 http://bitbucket.org/pypy/pypy/changeset/35e7f867cc40/ Log:Fix for @jit.elidable. Previously, it would elidably return None, even though it doesn't mean that it will stay None forever. diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -159,7 +159,7 @@ subentry = ProfilerSubEntry(entry.frame) self.calls[entry] = subentry return subentry -return None +raise class ProfilerContext(object): def __init__(self, profobj, entry): @@ -181,8 +181,11 @@ entry._stop(tt, it) if profobj.subcalls and self.previous: caller = jit.promote(self.previous.entry) -subentry = caller._get_or_make_subentry(entry, False) -if subentry is not None: +try: +subentry = caller._get_or_make_subentry(entry, False) +except KeyError: +pass +else: subentry._stop(tt, it) @@ -308,7 +311,7 @@ entry = ProfilerEntry(f_code) self.data[f_code] = entry return entry -return None +raise @jit.elidable def _get_or_make_builtin_entry(self, key, make=True): @@ -319,7 +322,7 @@ entry = ProfilerEntry(self.space.wrap(key)) self.builtin_data[key] = entry return entry -return None +raise def _enter_call(self, f_code): # we have a superb gc, no point in freelist :) @@ -332,8 +335,11 @@ if context is None: return self = jit.promote(self) -entry = self._get_or_make_entry(f_code, False) -if entry is not None: +try: +entry = self._get_or_make_entry(f_code, False) +except KeyError: +pass +else: context._stop(self, entry) self.current_context = context.previous @@ -347,8 +353,11 @@ if context is None: return self = jit.promote(self) -entry = self._get_or_make_builtin_entry(key, False) -if entry is not None: +try: +entry = self._get_or_make_builtin_entry(key, False) +except KeyError: +pass +else: context._stop(self, entry) self.current_context = context.previous ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix (probably) this jit.elidable here
Author: Armin Rigo Branch: Changeset: r69421:f3e717c94913 Date: 2014-02-25 14:57 +0100 http://bitbucket.org/pypy/pypy/changeset/f3e717c94913/ Log:Fix (probably) this jit.elidable here diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py --- a/pypy/objspace/std/intobject.py +++ b/pypy/objspace/std/intobject.py @@ -622,7 +622,6 @@ sys.maxint == 2147483647) -@jit.elidable def _string_to_int_or_long(space, w_source, string, base=10): w_longval = None value = 0 diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -709,5 +709,4 @@ result = ovfcheck(result + digit) except OverflowError: raise ParseStringOverflowError(p) - - +string_to_int._elidable_function_ = True ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: fix abort_if_needed
Author: Remi Meier Branch: c7-refactor Changeset: r860:a689a41e2fcd Date: 2014-02-25 15:22 +0100 http://bitbucket.org/pypy/stmgc/changeset/a689a41e2fcd/ Log:fix abort_if_needed diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -191,7 +191,7 @@ break; case TS_MUST_ABORT: -abort_with_mutex(); +stm_abort_transaction(); default: assert(!"commit: bad transaction_state"); ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: Add the WTM abstract.
Author: Armin Rigo Branch: extradoc Changeset: r5161:ffa0a239d1a2 Date: 2014-02-25 15:27 +0100 http://bitbucket.org/pypy/extradoc/changeset/ffa0a239d1a2/ Log:Add the WTM abstract. diff --git a/talk/wtm2014/abstract.rst b/talk/wtm2014/abstract.rst new file mode 100644 --- /dev/null +++ b/talk/wtm2014/abstract.rst @@ -0,0 +1,47 @@ +Abstract + + +As part of the PyPy project, we explore the usage of transactional +memory (TM) to enable parallelism for high-level, dynamic languages like +Python or Ruby. + +Most current software TM (STM) systems suffer from a big overhead when +they run on a single thread only (usually between 2-5x slowdown). They +try to scale to a large number of CPUs for the benefit of +parallelization to be greater than the penalty of the overhead. On the +other hand, while also software-based, the system presented here +initially focuses on a low CPU count (< 8). It uses an approach that can +keep the single-thread overhead very low (initial experiments with a +simple lisp interpreter suggest around 15%). As a consequence we already +see great speed-ups over single-threaded, non-STM execution by only +using 2 CPU cores. We achieve this with very-low-overhead read barriers +and very-low-overhead fast paths of write barriers. The enabling +mechanism, the Linux-only system call "remap_file_pages", allows for +creating several "views" on partially shared memory; every thread sees +one of these views. + +Our goal is to support a mixture of short to very long transactions. We +have an object-based STM system with an integrated GC handling the +typical high allocation rates of dynamic languages; in particular, it is +a generational GC, and the write barrier combines GC and STM roles, +always taking the fast path for recently-allocated objects. + +The next step is to finish integrating this system with PyPy, the Python +interpreter in Python, and its Just-In-Time compiler. This is +relatively straightforward and partly done already. We believe that the +result has got the potential to give good enough performance to rival or +exceed the HTM experiments which have been done before on Ruby [1]. +Future considerations also include optionally adding a hybrid (HyTM) +component to our system. + + + + +[1] Eliminating Global Interpreter Locks in Ruby through Hardware +Transactional Memory. + +Rei Odaira, Jose G. Castanos and Hisanobu Tomari. + +PPoPP '14 Proceedings of the 19th ACM SIGPLAN symposium on Principles and practice of parallel programming + +Pages 131-142 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: Add a bug here (bug tracker is read-only!)
Author: Armin Rigo Branch: extradoc Changeset: r5162:279c414f8907 Date: 2014-02-25 15:27 +0100 http://bitbucket.org/pypy/extradoc/changeset/279c414f8907/ Log:Add a bug here (bug tracker is read-only!) diff --git a/planning/jit.txt b/planning/jit.txt --- a/planning/jit.txt +++ b/planning/jit.txt @@ -201,3 +201,14 @@ - Movinging loop-invariant setitems out of the loops entierly. + +Bugs (bug tracker is down right now) + + +@jit.elidable annotations are completely ignored if the function has +"random side-effects". In 040f3ac28afb we display a warning, at least. +In order to turn the warning into an error, we need to review the +numerous places in PyPy where the warning occurs. The initial list: + +http://bpaste.net/show/182628/ + ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-remaining-smm: Remove AppTestKeywordsToBuiltinSanity. I don't think it makes any sense nowadays.
Author: Manuel Jacob Branch: remove-remaining-smm Changeset: r69423:eb5377110c02 Date: 2014-02-25 15:27 +0100 http://bitbucket.org/pypy/pypy/changeset/eb5377110c02/ Log:Remove AppTestKeywordsToBuiltinSanity. I don't think it makes any sense nowadays. diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py --- a/pypy/interpreter/test/test_gateway.py +++ b/pypy/interpreter/test/test_gateway.py @@ -823,46 +823,3 @@ assert space.is_true(w_res) assert len(called) == 1 assert isinstance(called[0], argument.Arguments) - - -class AppTestKeywordsToBuiltinSanity(object): - -def test_type(self): -class X(object): -def __init__(self, **kw): -pass -clash = type.__call__.func_code.co_varnames[0] - -X(**{clash: 33}) -type.__call__(X, **{clash: 33}) - -def test_object_new(self): -class X(object): -def __init__(self, **kw): -pass -clash = object.__new__.func_code.co_varnames[0] - -X(**{clash: 33}) -object.__new__(X, **{clash: 33}) - - -def test_dict_new(self): -clash = dict.__new__.func_code.co_varnames[0] - -dict(**{clash: 33}) -dict.__new__(dict, **{clash: 33}) - -def test_dict_init(self): -d = {} -clash = dict.__init__.func_code.co_varnames[0] - -d.__init__(**{clash: 33}) -dict.__init__(d, **{clash: 33}) - -def test_dict_update(self): -d = {} -clash = dict.update.func_code.co_varnames[0] - -d.update(**{clash: 33}) -dict.update(d, **{clash: 33}) - ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-remaining-smm: Fix complex <=> float comparison.
Author: Manuel Jacob Branch: remove-remaining-smm Changeset: r69422:bc9db28fcce0 Date: 2014-02-25 15:06 +0100 http://bitbucket.org/pypy/pypy/changeset/bc9db28fcce0/ Log:Fix complex <=> float comparison. diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -410,7 +410,8 @@ return space.newbool((self.realval == w_other.realval) and (self.imagval == w_other.imagval)) if (space.isinstance_w(w_other, space.w_int) or -space.isinstance_w(w_other, space.w_long)): +space.isinstance_w(w_other, space.w_long) or +space.isinstance_w(w_other, space.w_float)): if self.imagval: return space.w_False return space.eq(space.newfloat(self.realval), w_other) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: add demo_random.c
Author: Remi Meier Branch: c7-refactor Changeset: r859:2028836db0fa Date: 2014-02-25 15:22 +0100 http://bitbucket.org/pypy/stmgc/changeset/2028836db0fa/ Log:add demo_random.c diff --git a/c7/demo/demo_random.c b/c7/demo/demo_random.c new file mode 100644 --- /dev/null +++ b/c7/demo/demo_random.c @@ -0,0 +1,391 @@ +#include +#include +#include +#include +#include +#include + +#include "stmgc.h" + +#define NUMTHREADS 2 +#define STEPS_PER_THREAD 5000 +#define THREAD_STARTS 100 // how many restarts of threads +#define SHARED_ROOTS 3 +#define MAXROOTS 1000 + + +// SUPPORT +struct node_s; +typedef TLPREFIX struct node_s node_t; +typedef node_t* nodeptr_t; +typedef object_t* objptr_t; + +struct node_s { +struct object_s hdr; +long value; +nodeptr_t next; +}; + + +static sem_t done; +__thread stm_thread_local_t stm_thread_local; + +// global and per-thread-data +time_t default_seed; +objptr_t shared_roots[SHARED_ROOTS]; + +struct thread_data { +unsigned int thread_seed; +objptr_t roots[MAXROOTS]; +int num_roots; +int num_roots_at_transaction_start; +int steps_left; +}; +__thread struct thread_data td; + + +#define PUSH_ROOT(p) (*(stm_thread_local.shadowstack++) = (object_t *)(p)) +#define POP_ROOT(p)((p) = (typeof(p))*(--stm_thread_local.shadowstack)) + +void init_shadow_stack(void) +{ +object_t **s = (object_t **)malloc(1000 * sizeof(object_t *)); +assert(s); +stm_thread_local.shadowstack = s; +stm_thread_local.shadowstack_base = s; +} + +void done_shadow_stack(void) +{ +free(stm_thread_local.shadowstack_base); +stm_thread_local.shadowstack = NULL; +stm_thread_local.shadowstack_base = NULL; +} + + +ssize_t stmcb_size_rounded_up(struct object_s *ob) +{ +return sizeof(struct node_s); +} + +void stmcb_trace(struct object_s *obj, void visit(object_t **)) +{ +struct node_s *n; +n = (struct node_s*)obj; +visit((object_t **)&n->next); +} + +void _push_shared_roots() +{ +int i; +for (i = 0; i < SHARED_ROOTS; i++) { +PUSH_ROOT(shared_roots[i]); +} +} + +void _pop_shared_roots() +{ +int i; +for (i = 0; i < SHARED_ROOTS; i++) { +POP_ROOT(shared_roots[SHARED_ROOTS - i - 1]); +} +} + +int get_rand(int max) +{ +if (max == 0) +return 0; +return (int)(rand_r(&td.thread_seed) % (unsigned int)max); +} + +objptr_t get_random_root() +{ +int num = get_rand(2); +if (num == 0 && td.num_roots > 0) { +num = get_rand(td.num_roots); +return td.roots[num]; +} +else { +num = get_rand(SHARED_ROOTS); +return shared_roots[num]; +} +} + +void reload_roots() +{ +int i; +assert(td.num_roots == td.num_roots_at_transaction_start); +for (i = td.num_roots_at_transaction_start - 1; i >= 0; i--) { +if (td.roots[i]) +POP_ROOT(td.roots[i]); +} + +for (i = 0; i < td.num_roots_at_transaction_start; i++) { +if (td.roots[i]) +PUSH_ROOT(td.roots[i]); +} +} + +void push_roots() +{ +int i; +for (i = td.num_roots_at_transaction_start; i < td.num_roots; i++) { +if (td.roots[i]) +PUSH_ROOT(td.roots[i]); +} +} + +void pop_roots() +{ +int i; +for (i = td.num_roots - 1; i >= td.num_roots_at_transaction_start; i--) { +if (td.roots[i]) +POP_ROOT(td.roots[i]); +} +} + +void del_root(int idx) +{ +int i; +assert(idx >= td.num_roots_at_transaction_start); + +for (i = idx; i < td.num_roots - 1; i++) +td.roots[i] = td.roots[i + 1]; +td.num_roots--; +} + +void add_root(objptr_t r) +{ +if (r && td.num_roots < MAXROOTS) { +td.roots[td.num_roots++] = r; +} +} + + +void read_barrier(objptr_t p) +{ +if (p != NULL) { +stm_read(p); +} +} + +void write_barrier(objptr_t p) +{ +if (p != NULL) { +stm_write(p); +} +} + + + +objptr_t simple_events(objptr_t p, objptr_t _r) +{ +nodeptr_t w_r; +int k = get_rand(8); +int num; + +switch (k) { +case 0: // remove a root +if (td.num_roots > td.num_roots_at_transaction_start) { +num = td.num_roots_at_transaction_start ++ get_rand(td.num_roots - td.num_roots_at_transaction_start); +del_root(num); +} +break; +case 1: // add 'p' to roots +add_root(p); +break; +case 2: // set 'p' to point to a root +if (_r) +p = _r; +break; +case 3: // allocate fresh 'p' +push_roots(); +p = stm_allocate(sizeof(struct node_s)); +pop_roots(); +/* reload_roots not necessary, all are old after start_transaction */ +break; +case 4: // read and validate 'p' +read_barrier(p); +break; +case 5: // only do a stm_write_barrier +write_barrier(p); +break; +case 6: // follow p->next +if (p) { +read_barrier(p); +p = (objptr_t)(((nodeptr_
[pypy-commit] jitviewer default: This runs fine in CPython too, now.
Author: Armin Rigo Branch: Changeset: r256:e0b82d426d01 Date: 2014-02-25 15:59 +0100 http://bitbucket.org/pypy/jitviewer/changeset/e0b82d426d01/ Log:This runs fine in CPython too, now. diff --git a/bin/jitviewer.py b/bin/jitviewer.py --- a/bin/jitviewer.py +++ b/bin/jitviewer.py @@ -6,10 +6,5 @@ pythonpath = os.path.dirname(os.path.dirname(script_path)) sys.path.append(pythonpath) -# Check we are running with PyPy first. -if not '__pypy__' in sys.builtin_module_names: -from _jitviewer.misc import failout -failout("jitviewer must be run with PyPy") - from _jitviewer.app import main main(sys.argv) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: fix for race condition (see comment in pages.h for PRIVATE_PAGE)
Author: Remi Meier Branch: c7-refactor Changeset: r861:4915e227b68f Date: 2014-02-25 16:00 +0100 http://bitbucket.org/pypy/stmgc/changeset/4915e227b68f/ Log:fix for race condition (see comment in pages.h for PRIVATE_PAGE) diff --git a/c7/stm/pages.c b/c7/stm/pages.c --- a/c7/stm/pages.c +++ b/c7/stm/pages.c @@ -110,6 +110,7 @@ static void _pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) { +/* narrow the range of pages to privatize from the end: */ while (flag_page_private[pagenum + count - 1] == PRIVATE_PAGE) { if (!--count) return; diff --git a/c7/stm/pages.h b/c7/stm/pages.h --- a/c7/stm/pages.h +++ b/c7/stm/pages.h @@ -19,17 +19,21 @@ static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count); //static void pages_make_shared_again(uintptr_t pagenum, uintptr_t count); +static void mutex_pages_lock(void); +static void mutex_pages_unlock(void); + inline static void pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) { +mutex_pages_lock(); while (flag_page_private[pagenum] == PRIVATE_PAGE) { -if (!--count) +if (!--count) { +mutex_pages_unlock(); return; +} pagenum++; } +mutex_pages_unlock(); _pages_privatize(pagenum, count, full); } -static void mutex_pages_lock(void); -static void mutex_pages_unlock(void); - //static bool is_fully_in_shared_pages(object_t *obj); -- not needed? ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-remaining-smm: I think this is what we actually want to test: normally providing a 'self' keyword when calling a type fails, but not if the first keyword of the type's __init
Author: Manuel Jacob Branch: remove-remaining-smm Changeset: r69425:c890c07b80a9 Date: 2014-02-25 16:18 +0100 http://bitbucket.org/pypy/pypy/changeset/c890c07b80a9/ Log:I think this is what we actually want to test: normally providing a 'self' keyword when calling a type fails, but not if the first keyword of the type's __init__ method is renamed to something else than 'self'. diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py --- a/pypy/interpreter/test/test_gateway.py +++ b/pypy/interpreter/test/test_gateway.py @@ -826,10 +826,9 @@ class AppTestKeywordsToBuiltinSanity(object): - def test_type(self): class X(object): -def __init__(self, **kw): +def __init__(myself, **kw): pass clash = type.__call__.func_code.co_varnames[0] @@ -845,7 +844,6 @@ X(**{clash: 33}) object.__new__(X, **{clash: 33}) - def test_dict_new(self): clash = dict.__new__.func_code.co_varnames[0] @@ -865,4 +863,3 @@ d.update(**{clash: 33}) dict.update(d, **{clash: 33}) - ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-remaining-smm: Back out changeset eb5377110c02.
Author: Manuel Jacob Branch: remove-remaining-smm Changeset: r69424:2282f75f89c8 Date: 2014-02-25 16:09 +0100 http://bitbucket.org/pypy/pypy/changeset/2282f75f89c8/ Log:Back out changeset eb5377110c02. diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py --- a/pypy/interpreter/test/test_gateway.py +++ b/pypy/interpreter/test/test_gateway.py @@ -823,3 +823,46 @@ assert space.is_true(w_res) assert len(called) == 1 assert isinstance(called[0], argument.Arguments) + + +class AppTestKeywordsToBuiltinSanity(object): + +def test_type(self): +class X(object): +def __init__(self, **kw): +pass +clash = type.__call__.func_code.co_varnames[0] + +X(**{clash: 33}) +type.__call__(X, **{clash: 33}) + +def test_object_new(self): +class X(object): +def __init__(self, **kw): +pass +clash = object.__new__.func_code.co_varnames[0] + +X(**{clash: 33}) +object.__new__(X, **{clash: 33}) + + +def test_dict_new(self): +clash = dict.__new__.func_code.co_varnames[0] + +dict(**{clash: 33}) +dict.__new__(dict, **{clash: 33}) + +def test_dict_init(self): +d = {} +clash = dict.__init__.func_code.co_varnames[0] + +d.__init__(**{clash: 33}) +dict.__init__(d, **{clash: 33}) + +def test_dict_update(self): +d = {} +clash = dict.update.func_code.co_varnames[0] + +d.update(**{clash: 33}) +dict.update(d, **{clash: 33}) + ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: I think that with a REMAPPING_PAGE intermediate value it becomes
Author: Armin Rigo Branch: c7-refactor Changeset: r862:a396ed3087b8 Date: 2014-02-25 16:21 +0100 http://bitbucket.org/pypy/stmgc/changeset/a396ed3087b8/ Log:I think that with a REMAPPING_PAGE intermediate value it becomes simply this. diff --git a/c7/stm/pages.c b/c7/stm/pages.c --- a/c7/stm/pages.c +++ b/c7/stm/pages.c @@ -93,7 +93,7 @@ void *localpg = stm_object_pages + localpgoff * 4096UL; void *otherpg = stm_object_pages + otherpgoff * 4096UL; -memset(flag_page_private + pagenum, PRIVATE_PAGE, count); +memset(flag_page_private + pagenum, REMAPPING_PAGE, count); d_remap_file_pages(localpg, count * 4096, pgoff2); uintptr_t i; if (full) { @@ -106,6 +106,8 @@ if (count > 1) pagecopy(localpg + 4096 * (count-1), otherpg + 4096 * (count-1)); } +write_fence(); +memset(flag_page_private + pagenum, PRIVATE_PAGE, count); } static void _pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) diff --git a/c7/stm/pages.h b/c7/stm/pages.h --- a/c7/stm/pages.h +++ b/c7/stm/pages.h @@ -7,9 +7,11 @@ physical page (the one that is within the segment 0 mmap address). */ SHARED_PAGE, -/* Page is private for each segment. If we obtain this value outside - a mutex_pages_lock(), there might be a race: the value can say - PRIVATE_PAGE before the page is really un-shared. */ +/* For only one range of pages at a time, around the call to + remap_file_pages() that un-shares the pages (SHARED -> PRIVATE). */ +REMAPPING_PAGE, + +/* Page is private for each segment. */ PRIVATE_PAGE, }; @@ -24,15 +26,14 @@ inline static void pages_privatize(uintptr_t pagenum, uintptr_t count, bool full) { -mutex_pages_lock(); +/* This is written a bit carefully so that a call with a constant + count == 1 will turn this loop into just one "if". */ while (flag_page_private[pagenum] == PRIVATE_PAGE) { if (!--count) { -mutex_pages_unlock(); return; } pagenum++; } -mutex_pages_unlock(); _pages_privatize(pagenum, count, full); } ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: Add a debugging check that fails right now if we run more than 2 threads
Author: Armin Rigo Branch: c7-refactor Changeset: r863:a1bc43587591 Date: 2014-02-25 16:53 +0100 http://bitbucket.org/pypy/stmgc/changeset/a1bc43587591/ Log:Add a debugging check that fails right now if we run more than 2 threads diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -160,6 +160,9 @@ STM_PSEGMENT->transaction_state = (jmpbuf != NULL ? TS_REGULAR : TS_INEVITABLE); STM_SEGMENT->jmpbuf_ptr = jmpbuf; +#ifndef NDEBUG +STM_PSEGMENT->running_pthread = pthread_self(); +#endif STM_PSEGMENT->shadowstack_at_start_of_transaction = tl->shadowstack; STM_SEGMENT->nursery_end = NURSERY_END; @@ -340,6 +343,7 @@ { assert(!_has_mutex()); assert(STM_PSEGMENT->safe_point == SP_RUNNING); +assert(STM_PSEGMENT->running_pthread == pthread_self()); bool has_any_overflow_object = (STM_PSEGMENT->objects_pointing_to_nursery != NULL); @@ -449,6 +453,7 @@ default: assert(!"abort: bad transaction_state"); } +assert(STM_PSEGMENT->running_pthread == pthread_self()); /* throw away the content of the nursery */ throw_away_nursery(); diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -5,6 +5,7 @@ #include #include #include +#include // @@ -117,6 +118,11 @@ /* In case of abort, we restore the 'shadowstack' field. */ object_t **shadowstack_at_start_of_transaction; + +/* For debugging */ +#ifndef NDEBUG +pthread_t running_pthread; +#endif }; enum /* safe_point */ { diff --git a/c7/stm/sync.c b/c7/stm/sync.c --- a/c7/stm/sync.c +++ b/c7/stm/sync.c @@ -1,4 +1,3 @@ -#include #include #include #include ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc c7-refactor: Add *_no_abort() versions for cond_wait() and mutex_lock(). Needed
Author: Armin Rigo Branch: c7-refactor Changeset: r864:30bde5ed0833 Date: 2014-02-25 17:16 +0100 http://bitbucket.org/pypy/stmgc/changeset/30bde5ed0833/ Log:Add *_no_abort() versions for cond_wait() and mutex_lock(). Needed if we don't have our own segment so far. diff --git a/c7/demo/demo_random.c b/c7/demo/demo_random.c --- a/c7/demo/demo_random.c +++ b/c7/demo/demo_random.c @@ -7,7 +7,7 @@ #include "stmgc.h" -#define NUMTHREADS 2 +#define NUMTHREADS 3 #define STEPS_PER_THREAD 5000 #define THREAD_STARTS 100 // how many restarts of threads #define SHARED_ROOTS 3 diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -149,7 +149,7 @@ void _stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf) { -mutex_lock(); +mutex_lock_no_abort(); /* GS invalid before this point! */ acquire_thread_segment(tl); diff --git a/c7/stm/fprintcolor.c b/c7/stm/fprintcolor.c --- a/c7/stm/fprintcolor.c +++ b/c7/stm/fprintcolor.c @@ -13,7 +13,8 @@ char buffer[2048]; va_list ap; int result; -int size = (int)sprintf(buffer, "\033[%dm", dprintfcolor()); +int size = (int)sprintf(buffer, "\033[%dm[%lx]", dprintfcolor(), +(long)pthread_self()); assert(size >= 0); va_start(ap, format); diff --git a/c7/stm/sync.c b/c7/stm/sync.c --- a/c7/stm/sync.c +++ b/c7/stm/sync.c @@ -65,13 +65,17 @@ stm_fatalerror("syscall(arch_prctl, ARCH_SET_GS): %m\n"); } -static inline void mutex_lock(void) +static inline void mutex_lock_no_abort(void) { assert(!_has_mutex_here); if (UNLIKELY(pthread_mutex_lock(&sync_ctl.global_mutex) != 0)) stm_fatalerror("pthread_mutex_lock: %m\n"); assert((_has_mutex_here = true, 1)); +} +static inline void mutex_lock(void) +{ +mutex_lock_no_abort(); if (STM_PSEGMENT->transaction_state == TS_MUST_ABORT) abort_with_mutex(); } @@ -87,7 +91,7 @@ assert((_has_mutex_here = false, 1)); } -static inline void cond_wait(enum cond_type_e ctype) +static inline void cond_wait_no_abort(enum cond_type_e ctype) { #ifdef STM_NO_COND_WAIT stm_fatalerror("*** cond_wait/%d called!\n", (int)ctype); @@ -97,7 +101,11 @@ if (UNLIKELY(pthread_cond_wait(&sync_ctl.cond[ctype], &sync_ctl.global_mutex) != 0)) stm_fatalerror("pthread_cond_wait/%d: %m\n", (int)ctype); +} +static inline void cond_wait(enum cond_type_e ctype) +{ +cond_wait_no_abort(ctype); if (STM_PSEGMENT->transaction_state == TS_MUST_ABORT) abort_with_mutex(); } @@ -148,7 +156,7 @@ /* Wait and retry. It is guaranteed that any thread releasing its segment will do so by acquiring the mutex and calling cond_signal(C_RELEASE_THREAD_SEGMENT). */ -cond_wait(C_RELEASE_THREAD_SEGMENT); +cond_wait_no_abort(C_RELEASE_THREAD_SEGMENT); goto retry; got_num: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Kill most of pypy.objspace.std.model, move the type registration to pypy.objspace.std.objspace.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69426:c13b140abc63 Date: 2014-02-25 17:56 +0100 http://bitbucket.org/pypy/pypy/changeset/c13b140abc63/ Log:Kill most of pypy.objspace.std.model, move the type registration to pypy.objspace.std.objspace. diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py --- a/pypy/objspace/std/intobject.py +++ b/pypy/objspace/std/intobject.py @@ -584,6 +584,16 @@ _divmod, ovf2small=_divmod_ovf2small) +def setup_prebuilt(space): +if space.config.objspace.std.withprebuiltint: +W_IntObject.PREBUILT = [] +for i in range(space.config.objspace.std.prebuiltintfrom, + space.config.objspace.std.prebuiltintto): +W_IntObject.PREBUILT.append(W_IntObject(i)) +else: +W_IntObject.PREBUILT = None + + def wrapint(space, x): if not space.config.objspace.std.withprebuiltint: return W_IntObject(x) diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -1,232 +1,19 @@ -""" -The full list of which Python types and which implementation we want -to provide in this version of PyPy, along with conversion rules. -""" +from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.baseobjspace import W_Root, ObjSpace -import pypy.interpreter.pycode -import pypy.interpreter.special - -option_to_typename = { -"withsmalllong" : ["smalllongobject.W_SmallLongObject"], -"withstrbuf" : ["strbufobject.W_StringBufferObject"], -} IDTAG_INT = 1 IDTAG_LONG= 3 IDTAG_FLOAT = 5 IDTAG_COMPLEX = 7 -class StdTypeModel: - -def __init__(self, config): -"""NOT_RPYTHON: inititialization only""" -self.config = config -# All the Python types that we want to provide in this StdObjSpace - -# The object implementations that we want to 'link' into PyPy must be -# imported here. This registers them into the multimethod tables, -# *before* the type objects are built from these multimethod tables. -from pypy.objspace.std import objectobject -from pypy.objspace.std import boolobject -from pypy.objspace.std import intobject -from pypy.objspace.std import floatobject -from pypy.objspace.std import complexobject -from pypy.objspace.std import tupleobject -from pypy.objspace.std import listobject -from pypy.objspace.std import dictmultiobject -from pypy.objspace.std import setobject -from pypy.objspace.std import basestringtype -from pypy.objspace.std import bytesobject -from pypy.objspace.std import bytearrayobject -from pypy.objspace.std import typeobject -from pypy.objspace.std import sliceobject -from pypy.objspace.std import longobject -from pypy.objspace.std import noneobject -from pypy.objspace.std import iterobject -from pypy.objspace.std import unicodeobject -from pypy.objspace.std import dictproxyobject -from pypy.objspace.std import proxyobject - - -self.pythontypes = [] -self.pythontypes.append(objectobject.W_ObjectObject.typedef) -self.pythontypes.append(typeobject.W_TypeObject.typedef) -self.pythontypes.append(noneobject.W_NoneObject.typedef) -self.pythontypes.append(tupleobject.W_TupleObject.typedef) -self.pythontypes.append(listobject.W_ListObject.typedef) -self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef) -self.pythontypes.append(setobject.W_SetObject.typedef) -self.pythontypes.append(setobject.W_FrozensetObject.typedef) -self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef) -self.pythontypes.append(basestringtype.basestring_typedef) -self.pythontypes.append(bytesobject.W_BytesObject.typedef) -self.pythontypes.append(bytearrayobject.W_BytearrayObject.typedef) -self.pythontypes.append(unicodeobject.W_UnicodeObject.typedef) -self.pythontypes.append(intobject.W_IntObject.typedef) -self.pythontypes.append(boolobject.W_BoolObject.typedef) -self.pythontypes.append(longobject.W_LongObject.typedef) -self.pythontypes.append(floatobject.W_FloatObject.typedef) -self.pythontypes.append(complexobject.W_ComplexObject.typedef) -self.pythontypes.append(sliceobject.W_SliceObject.typedef) - -# the set of implementation types -self.typeorder = { -objectobject.W_ObjectObject: [], -# XXX: Bool/Int/Long are pythontypes but still included here -# for delegation to Float/Complex -boolobject.W_BoolObject: [], -intobject.W_IntObject: [], -floatobject.W_FloatObject: [], -typeobject.W_TypeObject: [], -sliceobject.W_SliceObject: [], -longobject.W_LongObject: [], -
[pypy-commit] pypy int_w-refactor: gateway_int_w now has the very same semantics as int_w
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69433:970e75bb2953 Date: 2014-02-25 17:56 +0100 http://bitbucket.org/pypy/pypy/changeset/970e75bb2953/ Log:gateway_int_w now has the very same semantics as int_w diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1420,11 +1420,7 @@ return w_obj.ord(self) # This is all interface for gateway.py. -def gateway_int_w(self, w_obj): -if self.isinstance_w(w_obj, self.w_float): -raise OperationError(self.w_TypeError, -self.wrap("integer argument expected, got float")) -return self.int_w(self.int(w_obj)) +gateway_int_w = int_w def gateway_float_w(self, w_obj): return self.float_w(self.float(w_obj)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: add a passing test and a comment explaining why the test was not failing
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69432:dc1874f92984 Date: 2014-02-25 17:54 +0100 http://bitbucket.org/pypy/pypy/changeset/dc1874f92984/ Log:add a passing test and a comment explaining why the test was not failing diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1262,7 +1262,10 @@ raise oefmt(self.w_TypeError, "%s must be an integer, not %T", objdescr, w_obj) try: -index = self.int_w(w_index) +# allow_conversion=False it's not really necessary because the +# return type of __index__ is already checked by space.index(), +# but there is no reason to allow conversions anyway +index = self.int_w(w_index, allow_conversion=False) except OperationError, err: if not err.match(self, self.w_OverflowError): raise diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -842,6 +842,26 @@ except TypeError: pass +def test_mul___index__(self): +class MyInt(object): + def __init__(self, x): +self.x = x + + def __int__(self): +return self.x + +class MyIndex(object): + def __init__(self, x): +self.x = x + + def __index__(self): +return self.x + +assert [0] * MyIndex(3) == [0, 0, 0] +raises(TypeError, "[0]*MyInt(3)") +raises(TypeError, "[0]*MyIndex(MyInt(3))") + + def test_index(self): c = range(10) assert c.index(0) == 0 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: add a failing test which should pass at the end of this branch
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69428:ce4d4ceb14e2 Date: 2014-02-24 11:50 +0100 http://bitbucket.org/pypy/pypy/changeset/ce4d4ceb14e2/ Log:add a failing test which should pass at the end of this branch diff --git a/pypy/module/struct/test/test_struct.py b/pypy/module/struct/test/test_struct.py --- a/pypy/module/struct/test/test_struct.py +++ b/pypy/module/struct/test/test_struct.py @@ -7,7 +7,7 @@ class AppTestStruct(object): -spaceconfig = dict(usemodules=['struct']) +spaceconfig = dict(usemodules=['struct', 'micronumpy']) def setup_class(cls): """ @@ -19,7 +19,7 @@ return struct """) cls.w_native_is_bigendian = cls.space.wrap(native_is_bigendian) - +cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def test_error(self): """ @@ -384,6 +384,18 @@ assert self.struct.unpack("ii", b) == (62, 12) raises(self.struct.error, self.struct.unpack, "i", b) +def test_numpy_dtypes(self): +if self.runappdirect: +from numpy.core.multiarray import typeinfo +else: +from _numpypy.multiarray import typeinfo +float64 = typeinfo['DOUBLE'][4] +obj = float64(42.3) +data = self.struct.pack('d', obj) +obj2, = self.struct.unpack('d', data) +assert type(obj2) is float +assert obj2 == 42.3 + class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: a branch where to refactor the semantics of space.int_w and space.float_w
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69427:6bb8ab7e58a7 Date: 2014-02-24 11:46 +0100 http://bitbucket.org/pypy/pypy/changeset/6bb8ab7e58a7/ Log:a branch where to refactor the semantics of space.int_w and space.float_w ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: start reviewing all usages of int_w(): we cannot use fake ints as indexes
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69430:ea3291c41c47 Date: 2014-02-25 17:30 +0100 http://bitbucket.org/pypy/pypy/changeset/ea3291c41c47/ Log:start reviewing all usages of int_w(): we cannot use fake ints as indexes diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -92,7 +92,7 @@ i = 2 * HUGEVAL_BYTES addrstring = [' '] * i while True: -n = space.int_w(space.and_(w_id, w_0x0F)) +n = space.int_w(space.and_(w_id, w_0x0F), allow_conversion=False) n += ord('0') if n > ord('9'): n += (ord('a') - ord('9') - 1) @@ -1238,7 +1238,7 @@ start, stop, step, length = w_index_or_slice.indices4(self, seqlength) else: -start = self.int_w(w_index_or_slice) +start = self.int_w(w_index_or_slice, allow_conversion=False) if start < 0: start += seqlength if not (0 <= start < seqlength): diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -170,6 +170,18 @@ for step in indices[1:]: assert b[start:stop:step] == s[start:stop:step] +def test_getitem_only_ints(self): +class MyInt(object): + def __init__(self, x): +self.x = x + + def __int__(self): +return self.x + +buf = buffer('hello world') +raises(TypeError, "buf[MyInt(0)]") +raises(TypeError, "buf[MyInt(0):MyInt(5)]") + class AppTestMemoryView: def test_basic(self): v = memoryview("abc") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: first step: change the meaning of space.int_w: now by default it also accepts objects which implements __int__, except floats. You can trigger the old behavior by pa
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69429:7e1beef017c9 Date: 2014-02-25 10:49 +0100 http://bitbucket.org/pypy/pypy/changeset/7e1beef017c9/ Log:first step: change the meaning of space.int_w: now by default it also accepts objects which implements __int__, except floats. You can trigger the old behavior by passing allow_conversion=False diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -201,7 +201,15 @@ def unicode_w(self, space): self._typed_unwrap_error(space, "unicode") -def int_w(self, space): +def int_w(self, space, allow_conversion=True): +# note that W_IntObject.int_w has a fast path and W_FloatObject.int_w +# raises +w_obj = self +if allow_conversion: +w_obj = space.int(self) +return w_obj._int_w(space) + +def _int_w(self, space): self._typed_unwrap_error(space, "integer") def float_w(self, space): @@ -220,8 +228,7 @@ def int(self, space): w_impl = space.lookup(self, '__int__') if w_impl is None: -raise oefmt(space.w_TypeError, -"unsupported operand type for int(): '%T'", self) +self._typed_unwrap_error(space, "integer") w_result = space.get_and_call_function(w_impl, self) if (space.isinstance_w(w_result, space.w_int) or @@ -1348,8 +1355,19 @@ 'argument must be a string without NUL characters')) return rstring.assert_str0(result) -def int_w(self, w_obj): -return w_obj.int_w(self) +def int_w(self, w_obj, allow_conversion=True): +""" +Unwrap an app-level int object into an interpret-level int. + +If allow_conversion==True, w_obj might be of any type which implements +__int__, *except* floats which are explicitly rejected. This is the +same logic as CPython's PyArg_ParseTuple. If you want to also allow +floats, you can call space.int_w(space.int(w_obj)). + +If allow_conversion=False, w_obj needs to be an app-level int or a +subclass. +""" +return w_obj.int_w(self, allow_conversion) def int(self, w_obj): return w_obj.int(self) diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -106,7 +106,7 @@ def len(self, x): return len(x) -def int_w(self, x): +def int_w(self, x, allow_conversion=True): return x def eq_w(self, x, y): diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py --- a/pypy/interpreter/test/test_objspace.py +++ b/pypy/interpreter/test/test_objspace.py @@ -167,6 +167,40 @@ self.space.setattr(w_oldstyle, self.space.wrap("__call__"), w_func) assert is_callable(w_oldstyle) +def test_int_w(self): +space = self.space +w_x = space.wrap(42) +assert space.int_w(w_x) == 42 +assert space.int_w(w_x, allow_conversion=False) == 42 +# +w_x = space.wrap(44.0) +space.raises_w(space.w_TypeError, space.int_w, w_x) +space.raises_w(space.w_TypeError, space.int_w, w_x, allow_conversion=False) +# +w_instance = self.space.appexec([], """(): +class MyInt(object): +def __int__(self): +return 43 +return MyInt() +""") +assert space.int_w(w_instance) == 43 +space.raises_w(space.w_TypeError, space.int_w, w_instance, allow_conversion=False) +# +w_instance = self.space.appexec([], """(): +class MyInt(object): +def __int__(self): +return 43 + +class AnotherInt(object): +def __int__(self): +return MyInt() + +return AnotherInt() +""") +space.raises_w(space.w_TypeError, space.int_w, w_instance) +space.raises_w(space.w_TypeError, space.int_w, w_instance, allow_conversion=False) + + def test_interp_w(self): w = self.space.wrap w_bltinfunction = self.space.builtin.get('len') diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py --- a/pypy/module/cppyy/test/test_zjit.py +++ b/pypy/module/cppyy/test/test_zjit.py @@ -141,7 +141,7 @@ def is_w(self, w_one, w_two): return w_one is w_two -def int_w(self, w_obj): +def int_w(self, w_obj, allow_conversion=True): assert isinstance(w_obj, FakeInt) return w_obj.val diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -157,6 +157,7 @@ return w_obj.f
[pypy-commit] pypy int_w-refactor: this is hard to test, but CPython accepts only actual integers in sys.exit()
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69434:8854c318cb66 Date: 2014-02-25 18:00 +0100 http://bitbucket.org/pypy/pypy/changeset/8854c318cb66/ Log:this is hard to test, but CPython accepts only actual integers in sys.exit() diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py --- a/pypy/interpreter/main.py +++ b/pypy/interpreter/main.py @@ -134,7 +134,7 @@ exitcode = 0 else: try: -exitcode = space.int_w(w_exitcode) +exitcode = space.int_w(w_exitcode, allow_conversion=False) except OperationError: # not an integer: print it to stderr msg = space.str_w(space.str(w_exitcode)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy int_w-refactor: more reviewing of int_w(): conversions are not allowed here
Author: Antonio Cuni Branch: int_w-refactor Changeset: r69431:8a8a32a743e3 Date: 2014-02-25 17:41 +0100 http://bitbucket.org/pypy/pypy/changeset/8a8a32a743e3/ Log:more reviewing of int_w(): conversions are not allowed here diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1217,7 +1217,7 @@ assert isinstance(w_index_or_slice, W_SliceObject) start, stop, step = w_index_or_slice.indices3(self, seqlength) else: -start = self.int_w(w_index_or_slice) +start = self.int_w(w_index_or_slice, allow_conversion=False) if start < 0: start += seqlength if not (0 <= start < seqlength): diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -1034,6 +1034,18 @@ assert len(b) == 13 assert str(b[12]) == "-0.0" +def test_getitem_only_ints(self): +class MyInt(object): + def __init__(self, x): +self.x = x + + def __int__(self): +return self.x + +a = self.array('i', [1, 2, 3, 4, 5, 6]) +raises(TypeError, "a[MyInt(0)]") +raises(TypeError, "a[MyInt(0):MyInt(5)]") + class AppTestArrayBuiltinShortcut(AppTestArray): spaceconfig = AppTestArray.spaceconfig.copy() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Kill model.UnwrapError.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69435:646434ae7b6d Date: 2014-02-25 18:08 +0100 http://bitbucket.org/pypy/pypy/changeset/646434ae7b6d/ Log:Kill model.UnwrapError. diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -34,7 +34,3 @@ if w_cls is not None and w_cls is not self: s += ' instance of %s' % self.w__class__ return '<%s>' % s - - -class UnwrapError(Exception): -pass diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -3,8 +3,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.objspace.std import (stdtypedef, frame, model, - transparent, callmethod) +from pypy.objspace.std import stdtypedef, frame, transparent, callmethod from pypy.objspace.descroperation import DescrOperation, raiseattrerror from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant from rpython.rlib.debug import make_sure_not_resized @@ -245,7 +244,7 @@ # _ this code is here to support testing only _ if isinstance(w_obj, W_Root): return w_obj.unwrap(self) -raise model.UnwrapError("cannot unwrap: %r" % w_obj) +raise TypeError("cannot unwrap: %r" % w_obj) def newint(self, intval): return wrapint(self, intval) diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -439,10 +439,6 @@ storage = strategy.erase(w_self) return W_DictMultiObject(space, strategy, storage) -def unwrap(w_self, space): -from pypy.objspace.std.model import UnwrapError -raise UnwrapError(w_self) - def is_heaptype(w_self): return w_self.flag_heaptype ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Kill W_Object.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69437:39f12449bcb7 Date: 2014-02-25 18:21 +0100 http://bitbucket.org/pypy/pypy/changeset/39f12449bcb7/ Log:Kill W_Object. diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -13,22 +13,3 @@ BINARY_OPS = dict(add='+', div='/', floordiv='//', mod='%', mul='*', sub='-', truediv='/', **BINARY_BITWISE_OPS) COMMUTATIVE_OPS = ('add', 'mul', 'and', 'or', 'xor') - - -# - -class W_Object(W_Root): -"Parent base class for wrapped objects provided by the StdObjSpace." -# Note that not all wrapped objects in the interpreter inherit from -# W_Object. (They inherit from W_Root.) -__slots__ = () - -def __repr__(self): -name = getattr(self, 'name', '') -if not isinstance(name, str): -name = '' -s = '%s(%s)' % (self.__class__.__name__, name) -w_cls = getattr(self, 'w__class__', None) -if w_cls is not None and w_cls is not self: -s += ' instance of %s' % self.w__class__ -return '<%s>' % s diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py --- a/pypy/objspace/std/proxyobject.py +++ b/pypy/objspace/std/proxyobject.py @@ -2,13 +2,8 @@ """ transparent list implementation """ -from pypy.objspace.std.model import W_Object +from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError -from pypy.interpreter import baseobjspace - -#class W_Transparent(W_Object): -#def __init__(self, w_controller): -#self.controller = w_controller def transparent_class(name, BaseCls): @@ -72,7 +67,6 @@ return W_Transparent W_Transparent = transparent_class('W_Transparent', baseobjspace.W_Root) -#W_TransparentObject = transparent_class('W_TransparentObject', W_Object) #from pypy.objspace.std.objecttype import object_typedef #W_TransparentObject.typedef = object_typedef diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1,13 +1,12 @@ -from pypy.objspace.std.model import W_Object +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.gateway import interp2app from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.interpreter.gateway import interp2app - class TestTypeObject: def test_not_acceptable_as_base_class(self): space = self.space -class W_Stuff(W_Object): +class W_Stuff(W_Root): pass def descr__new__(space, w_subtype): return space.allocate_instance(W_Stuff, w_subtype) diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -5,7 +5,6 @@ from pypy.interpreter.typedef import weakref_descr, GetSetProperty,\ descr_get_dict from pypy.interpreter.astcompiler.misc import mangle -from pypy.objspace.std.model import W_Object from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member from pypy.objspace.std.stdtypedef import StdTypeDef @@ -56,7 +55,7 @@ COMPARES_BY_IDENTITY = 1 OVERRIDES_EQ_CMP_OR_HASH = 2 -class W_TypeObject(W_Object): +class W_TypeObject(W_Root): lazyloaders = {} # can be overridden by specific instances # the version_tag changes if the dict or the inheritance hierarchy changes ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Kill W_ANY.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69436:e0681470078b Date: 2014-02-25 18:10 +0100 http://bitbucket.org/pypy/pypy/changeset/e0681470078b/ Log:Kill W_ANY. diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -17,8 +17,6 @@ # -W_ANY = W_Root - class W_Object(W_Root): "Parent base class for wrapped objects provided by the StdObjSpace." # Note that not all wrapped objects in the interpreter inherit from diff --git a/pypy/objspace/std/proxy_helpers.py b/pypy/objspace/std/proxy_helpers.py --- a/pypy/objspace/std/proxy_helpers.py +++ b/pypy/objspace/std/proxy_helpers.py @@ -3,9 +3,8 @@ of cyclic imports """ -from pypy.objspace.std.model import W_ANY, W_Object -from pypy.interpreter import baseobjspace from pypy.interpreter.argument import Arguments +from pypy.interpreter.baseobjspace import W_Root from rpython.tool.sourcetools import func_with_new_name def create_mm_names(classname, mm, is_local): @@ -34,7 +33,7 @@ return space.call_args(w_transparent_list.w_controller, args) function = func_with_new_name(function, mm.name) -mm.register(function, type_, *([W_ANY] * (mm.arity - 1))) +mm.register(function, type_, *([W_Root] * (mm.arity - 1))) def install_mm_trampoline(type_, mm, is_local): classname = type_.__name__[2:] @@ -50,7 +49,7 @@ return space.call_function(w_transparent_list.w_controller, space.wrap\ (op_name), *args_w) function = func_with_new_name(function, mm_name) -mm.register(function, type_, *([W_ANY] * (mm.arity - 1))) +mm.register(function, type_, *([W_Root] * (mm.arity - 1))) def is_special_doublearg(mm, type_): """ We specialcase when we've got two argument method for which ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Rename this test and uncomment additional asserts.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69440:745447db5195 Date: 2014-02-25 18:40 +0100 http://bitbucket.org/pypy/pypy/changeset/745447db5195/ Log:Rename this test and uncomment additional asserts. diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -420,16 +420,15 @@ raises(OverflowError, math.trunc, float("inf")) -def test_multimethod_slice(self): +def test_call_special(self): assert 5 .__add__(3.14) is NotImplemented assert 3.25 .__add__(5) == 8.25 -# xxx we are also a bit inconsistent about the following -#if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent -#assert 5 .__eq__(3.14) is NotImplemented -#assert 3.14 .__eq__(5) is False -#if hasattr(long, '__eq__'): # for py.test -A: CPython is inconsistent -#assert 5L .__eq__(3.14) is NotImplemented -#assert 3.14 .__eq__(5L) is False + +assert 5 .__eq__(3.14) is NotImplemented +assert 3.14 .__eq__(5) is False + +assert 5L .__eq__(3.14) is NotImplemented +assert 3.14 .__eq__(5L) is False def test_from_string(self): raises(ValueError, float, "\0") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Move rest of pypy.objspace.std.model into pypy.objspace.std.util.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69438:c7fe33d31de3 Date: 2014-02-25 18:30 +0100 http://bitbucket.org/pypy/pypy/changeset/c7fe33d31de3/ Log:Move rest of pypy.objspace.std.model into pypy.objspace.std.util. diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -272,7 +272,7 @@ if self.user_overridden_class: return None from rpython.rlib.longlong2float import float2longlong -from pypy.objspace.std.model import IDTAG_COMPLEX as tag +from pypy.objspace.std.util import IDTAG_COMPLEX as tag real = space.float_w(space.getattr(self, space.wrap("real"))) imag = space.float_w(space.getattr(self, space.wrap("imag"))) real_b = rbigint.fromrarith_int(float2longlong(real)) diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -172,7 +172,7 @@ if self.user_overridden_class: return None from rpython.rlib.longlong2float import float2longlong -from pypy.objspace.std.model import IDTAG_FLOAT as tag +from pypy.objspace.std.util import IDTAG_FLOAT as tag val = float2longlong(space.float_w(self)) b = rbigint.fromrarith_int(val) b = b.lshift(3).or_(rbigint.fromint(tag)) diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py --- a/pypy/objspace/std/intobject.py +++ b/pypy/objspace/std/intobject.py @@ -9,7 +9,7 @@ import sys from rpython.rlib import jit -from rpython.rlib.objectmodel import instantiate, import_from_mixin, specialize +from rpython.rlib.objectmodel import instantiate from rpython.rlib.rarithmetic import ( LONG_BIT, is_valid_int, ovfcheck, r_longlong, r_uint, string_to_int) from rpython.rlib.rbigint import rbigint @@ -22,10 +22,9 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec from pypy.objspace.std import newformat -from pypy.objspace.std.model import ( -BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT) from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.objspace.std.util import wrap_parsestringerror +from pypy.objspace.std.util import ( +BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT, wrap_parsestringerror) SENTINEL = object() @@ -689,7 +688,6 @@ buf = space.interp_w(Buffer, w_buffer) value, w_longval = _string_to_int_or_long(space, w_value, buf.as_str()) -ok = True else: base = space.int_w(w_base) diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py --- a/pypy/objspace/std/longobject.py +++ b/pypy/objspace/std/longobject.py @@ -15,10 +15,9 @@ WrappedDefault, interp2app, interpindirect2app, unwrap_spec) from pypy.objspace.std import newformat from pypy.objspace.std.intobject import W_AbstractIntObject -from pypy.objspace.std.model import ( -BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG) from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.objspace.std.util import wrap_parsestringerror +from pypy.objspace.std.util import ( +BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG, wrap_parsestringerror) def delegate_other(func): diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py deleted file mode 100644 --- a/pypy/objspace/std/model.py +++ /dev/null @@ -1,15 +0,0 @@ -from pypy.interpreter.baseobjspace import W_Root - - -IDTAG_INT = 1 -IDTAG_LONG= 3 -IDTAG_FLOAT = 5 -IDTAG_COMPLEX = 7 - - -CMP_OPS = dict(lt='<', le='<=', eq='==', ne='!=', gt='>', ge='>=') -BINARY_BITWISE_OPS = {'and': '&', 'lshift': '<<', 'or': '|', 'rshift': '>>', - 'xor': '^'} -BINARY_OPS = dict(add='+', div='/', floordiv='//', mod='%', mul='*', sub='-', - truediv='/', **BINARY_BITWISE_OPS) -COMMUTATIVE_OPS = ('add', 'mul', 'and', 'or', 'xor') diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py --- a/pypy/objspace/std/smalllongobject.py +++ b/pypy/objspace/std/smalllongobject.py @@ -13,7 +13,7 @@ from pypy.interpreter.gateway import WrappedDefault, unwrap_spec from pypy.objspace.std.intobject import W_AbstractIntObject from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject -from pypy.objspace.std.model import COMMUTATIVE_OPS +from pypy.objspace.std.util import COMMUTATIVE_OPS # XXX: breaks translation #LONGLONG_MIN = r_longlong(-1 << (LONGLONG_BIT - 1)) diff --git a/pypy/objspace/std/util.py b/pypy/objspace/std/util.py --- a/pypy/objspace/std/util.py +++ b/pypy/objspace/std/util.py @@ -2,6 +2,19 @@ from rpython.rlib.rstring import InvalidBaseError +IDTAG_INT = 1 +IDTAG_LONG= 3 +IDTAG_FLOAT
[pypy-commit] pypy kill-multimethod: Kill unused proxy_helpers.py. Make StdTypeDef an alias to TypeDef.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69441:6d0d93cd5c53 Date: 2014-02-25 18:47 +0100 http://bitbucket.org/pypy/pypy/changeset/6d0d93cd5c53/ Log:Kill unused proxy_helpers.py. Make StdTypeDef an alias to TypeDef. diff --git a/pypy/objspace/std/proxy_helpers.py b/pypy/objspace/std/proxy_helpers.py deleted file mode 100644 --- a/pypy/objspace/std/proxy_helpers.py +++ /dev/null @@ -1,90 +0,0 @@ - -""" Some transparent helpers, put here because -of cyclic imports -""" - -from pypy.interpreter.argument import Arguments -from pypy.interpreter.baseobjspace import W_Root -from rpython.tool.sourcetools import func_with_new_name - -def create_mm_names(classname, mm, is_local): -s = "" -if is_local: -s += "list_" -s += mm.name + "__" -s += "_".join([classname] + ["ANY"] * (mm.arity - 1)) -#if '__' + mm.name + '__' in mm.specialnames: -#return s, '__' + mm.name + '__' -if mm.specialnames: -return s, mm.specialnames[0] -return s, mm.name - -def install_general_args_trampoline(type_, mm, is_local, op_name): -def function(space, w_transparent_list, __args__): -args = __args__.prepend(space.wrap(op_name)) -return space.call_args(w_transparent_list.w_controller, args) - -function = func_with_new_name(function, mm.name) -mm.register(function, type_) - -def install_args_w_trampoline(type_, mm, is_local, op_name): -def function(space, w_transparent_list, *args_w): -args = Arguments(space, [space.wrap(op_name)] + list(args_w[:-1]) + args_w[-1]) -return space.call_args(w_transparent_list.w_controller, args) - -function = func_with_new_name(function, mm.name) -mm.register(function, type_, *([W_Root] * (mm.arity - 1))) - -def install_mm_trampoline(type_, mm, is_local): -classname = type_.__name__[2:] -mm_name, op_name = create_mm_names(classname, mm, is_local) - -if ['__args__'] == mm.argnames_after: -return install_general_args_trampoline(type_, mm, is_local, op_name) -if ['args_w'] == mm.argnames_after: -return install_args_w_trampoline(type_, mm, is_local, op_name) -assert not mm.argnames_after -# we search here for special-cased stuff -def function(space, w_transparent_list, *args_w): -return space.call_function(w_transparent_list.w_controller, space.wrap\ -(op_name), *args_w) -function = func_with_new_name(function, mm_name) -mm.register(function, type_, *([W_Root] * (mm.arity - 1))) - -def is_special_doublearg(mm, type_): -""" We specialcase when we've got two argument method for which -there exist reverse operation -""" -if mm.arity != 2: -return False - -if len(mm.specialnames) != 2: -return False - -# search over the signatures -for signature in mm.signatures(): -if signature == (type_.original, type_.original): -return True -return False - -def install_mm_special(type_, mm, is_local): -classname = type_.__name__[2:] -#mm_name, op_name = create_mm_names(classname, mm, is_local) - -def function(space, w_any, w_transparent_list): -retval = space.call_function(w_transparent_list.w_controller, space.wrap(mm.specialnames[1]), -w_any) -return retval - -function = func_with_new_name(function, mm.specialnames[0]) - -mm.register(function, type_.typedef.any, type_) - -def register_type(type_): -from pypy.objspace.std.stdtypedef import multimethods_defined_on - -for mm, is_local in multimethods_defined_on(type_.original): -if not mm.name.startswith('__'): -install_mm_trampoline(type_, mm, is_local) -if is_special_doublearg(mm, type_): -install_mm_special(type_, mm, is_local) diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -8,12 +8,8 @@ __all__ = ['StdTypeDef'] -class StdTypeDef(TypeDef): +StdTypeDef = TypeDef -def __init__(self, __name, __base=None, **rawdict): -"NOT_RPYTHON: initialization-time only." -TypeDef.__init__(self, __name, __base, **rawdict) -self.any = type("W_Any"+__name.title(), (baseobjspace.W_Root,), {'typedef': self}) @jit.unroll_safe def issubtypedef(a, b): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Remove multimethods sections from documentation.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69439:0d2003298f8b Date: 2014-02-25 18:34 +0100 http://bitbucket.org/pypy/pypy/changeset/0d2003298f8b/ Log:Remove multimethods sections from documentation. diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -384,105 +384,6 @@ .. _`Standard Interpreter Optimizations`: interpreter-optimizations.html -Multimethods - - -The Standard Object Space allows multiple object implementations per -Python type - this is based on multimethods_. For a description of the -multimethod variant that we implemented and which features it supports, -see the comment at the start of `pypy/objspace/std/multimethod.py`_. However, multimethods -alone are not enough for the Standard Object Space: the complete picture -spans several levels in order to emulate the exact Python semantics. - -Consider the example of the ``space.getitem(w_a, w_b)`` operation, -corresponding to the application-level syntax ``a[b]``. The Standard -Object Space contains a corresponding ``getitem`` multimethod and a -family of functions that implement the multimethod for various -combination of argument classes - more precisely, for various -combinations of the *interpreter-level* classes of the arguments. Here -are some examples of functions implementing the ``getitem`` -multimethod: - -* ``getitem__Tuple_ANY``: called when the first argument is a - W_TupleObject, this function converts its second argument to an - integer and performs tuple indexing. - -* ``getitem__Tuple_Slice``: called when the first argument is a - W_TupleObject and the second argument is a W_SliceObject. This - version takes precedence over the previous one if the indexing is - done with a slice object, and performs tuple slicing instead. - -* ``getitem__String_Slice``: called when the first argument is a - W_StringObject and the second argument is a slice object. - -Note how the multimethod dispatch logic helps writing new object -implementations without having to insert hooks into existing code. Note -first how we could have defined a regular method-based API that new -object implementations must provide, and call these methods from the -space operations. The problem with this approach is that some Python -operators are naturally binary or N-ary. Consider for example the -addition operation: for the basic string implementation it is a simple -concatenation-by-copy, but it can have a rather more subtle -implementation for strings done as ropes. It is also likely that -concatenating a basic string with a rope string could have its own -dedicated implementation - and yet another implementation for a rope -string with a basic string. With multimethods, we can have an -orthogonally-defined implementation for each combination. - -The multimethods mechanism also supports delegate functions, which are -converters between two object implementations. The dispatch logic knows -how to insert calls to delegates if it encounters combinations of -interp-level classes which is not directly implemented. For example, we -have no specific implementation for the concatenation of a basic string -and a StringSlice object; when the user adds two such strings, then the -StringSlice object is converted to a basic string (that is, a -temporarily copy is built), and the concatenation is performed on the -resulting pair of basic strings. This is similar to the C++ method -overloading resolution mechanism (but occurs at runtime). - -.. _multimethods: http://en.wikipedia.org/wiki/Multimethods - - -Multimethod slicing - -The complete picture is more complicated because the Python object model -is based on *descriptors*: the types ``int``, ``str``, etc. must have -methods ``__add__``, ``__mul__``, etc. that take two arguments including -the ``self``. These methods must perform the operation or return -``NotImplemented`` if the second argument is not of a type that it -doesn't know how to handle. - -The Standard Object Space creates these methods by *slicing* the -multimethod tables. Each method is automatically generated from a -subset of the registered implementations of the corresponding -multimethod. This slicing is performed on the first argument, in order -to keep only the implementations whose first argument's -interpreter-level class matches the declared Python-level type. - -For example, in a baseline PyPy, ``int.__add__`` is just calling the -function ``add__Int_Int``, which is the only registered implementation -for ``add`` whose first argument is an implementation of the ``int`` -Python type. On the other hand, if we enable integers implemented as -tagged pointers, then there is another matching implementation: -``add__SmallInt_SmallInt``. In this case, the Python-level method -``int.__add__`` is implemented by trying to dispatch between these two -functions based on the interp-level type of the two arguments. - -Sim
[pypy-commit] pypy kill-multimethod: Move std_dict_descr to pypy.interpreter.typedef.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69443:738f370ede8a Date: 2014-02-25 19:02 +0100 http://bitbucket.org/pypy/pypy/changeset/738f370ede8a/ Log:Move std_dict_descr to pypy.interpreter.typedef. diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -617,6 +617,7 @@ from pypy.interpreter.nestedscope import Cell from pypy.interpreter.special import NotImplemented, Ellipsis + def descr_get_dict(space, w_obj): w_dict = w_obj.getdict(space) if w_dict is None: @@ -637,6 +638,11 @@ return space.w_None return lifeline.get_any_weakref(space) +dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict, +doc="dictionary for instance variables (if defined)") +dict_descr.name = '__dict__' + + def generic_ne(space, w_obj1, w_obj2): if space.eq_w(w_obj1, w_obj2): return space.w_False diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -1,6 +1,4 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member -from pypy.interpreter.typedef import descr_get_dict, descr_set_dict -from pypy.interpreter.typedef import descr_del_dict from pypy.interpreter.baseobjspace import SpaceCache __all__ = ['StdTypeDef'] @@ -9,11 +7,6 @@ StdTypeDef = TypeDef -std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict, -doc="dictionary for instance variables (if defined)") -std_dict_descr.name = '__dict__' - - class TypeCache(SpaceCache): def build(cache, typedef): "NOT_RPYTHON: initialization-time only." diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -3,9 +3,9 @@ from pypy.interpreter.error import oefmt, OperationError from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter.typedef import weakref_descr, GetSetProperty,\ - descr_get_dict + descr_get_dict, dict_descr from pypy.interpreter.astcompiler.misc import mangle -from pypy.objspace.std.stdtypedef import std_dict_descr, Member +from pypy.objspace.std.stdtypedef import Member from pypy.objspace.std.stdtypedef import StdTypeDef from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, @@ -1032,7 +1032,7 @@ def create_dict_slot(w_self): if not w_self.hasdict: w_self.dict_w.setdefault('__dict__', - w_self.space.wrap(std_dict_descr)) + w_self.space.wrap(dict_descr)) w_self.hasdict = True def create_weakref_slot(w_self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Remove StdTypeDef alias and change all references.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69444:5a5429019418 Date: 2014-02-25 19:21 +0100 http://bitbucket.org/pypy/pypy/changeset/5a5429019418/ Log:Remove StdTypeDef alias and change all references. diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -2,7 +2,6 @@ from pypy.interpreter import argument, gateway from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.sliceobject import W_SliceObject from rpython.rlib.objectmodel import instantiate, we_are_translated, specialize from rpython.rlib.nonconst import NonConstant @@ -365,9 +364,8 @@ @specialize.memo() def see_typedef(space, typedef): assert isinstance(typedef, TypeDef) -if not isinstance(typedef, StdTypeDef): -for name, value in typedef.rawdict.items(): -space.wrap(value) +for name, value in typedef.rawdict.items(): +space.wrap(value) class FakeCompiler(object): pass diff --git a/pypy/objspace/std/basestringtype.py b/pypy/objspace/std/basestringtype.py --- a/pypy/objspace/std/basestringtype.py +++ b/pypy/objspace/std/basestringtype.py @@ -1,7 +1,7 @@ -from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.interpreter.typedef import TypeDef -basestring_typedef = StdTypeDef("basestring", +basestring_typedef = TypeDef("basestring", __doc__ = ("basestring cannot be instantiated; " "it is the base for str and unicode.") ) diff --git a/pypy/objspace/std/boolobject.py b/pypy/objspace/std/boolobject.py --- a/pypy/objspace/std/boolobject.py +++ b/pypy/objspace/std/boolobject.py @@ -6,8 +6,8 @@ from rpython.tool.sourcetools import func_renamer, func_with_new_name from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec +from pypy.interpreter.typedef import TypeDef from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject -from pypy.objspace.std.stdtypedef import StdTypeDef class W_BoolObject(W_IntObject): @@ -80,7 +80,7 @@ W_BoolObject.w_True = W_BoolObject(True) -W_BoolObject.typedef = StdTypeDef("bool", W_IntObject.typedef, +W_BoolObject.typedef = TypeDef("bool", W_IntObject.typedef, __doc__ = """bool(x) -> bool Returns True when the argument x is true, False otherwise. diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec from pypy.interpreter.signature import Signature +from pypy.interpreter.typedef import TypeDef from pypy.objspace.std.sliceobject import W_SliceObject -from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.stringmethods import StringMethods from pypy.objspace.std.util import get_positive_index @@ -891,7 +891,7 @@ """ -W_BytearrayObject.typedef = StdTypeDef( +W_BytearrayObject.typedef = TypeDef( "bytearray", __doc__ = BytearrayDocstrings.__doc__, __new__ = interp2app(W_BytearrayObject.descr_new), diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py --- a/pypy/objspace/std/bytesobject.py +++ b/pypy/objspace/std/bytesobject.py @@ -10,10 +10,10 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import ( WrappedDefault, interp2app, interpindirect2app, unwrap_spec) +from pypy.interpreter.typedef import TypeDef from pypy.objspace.std import newformat from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.formatting import mod_format -from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.stringmethods import StringMethods from pypy.objspace.std.unicodeobject import ( _get_encoding_and_errors, decode_object, unicode_from_encoded_object, @@ -782,7 +782,7 @@ return W_BytesObject(c) -W_BytesObject.typedef = StdTypeDef( +W_BytesObject.typedef = TypeDef( "str", basestring_typedef, __new__ = interp2app(W_BytesObject.descr_new), __doc__ = """str(object='') -> string diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -3,9 +3,9 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.objspace.std import newformat from pypy.objspace.std.floatobject import _hash_float -from pypy.objspace.std.stdtypedef import GetSetProperty, StdT
[pypy-commit] pypy kill-multimethod: Move issubtypedef into typeobject.py.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69442:cb191419517d Date: 2014-02-25 18:56 +0100 http://bitbucket.org/pypy/pypy/changeset/cb191419517d/ Log:Move issubtypedef into typeobject.py. diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -1,9 +1,7 @@ -from pypy.interpreter import baseobjspace from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import descr_del_dict from pypy.interpreter.baseobjspace import SpaceCache -from rpython.rlib import jit __all__ = ['StdTypeDef'] @@ -11,29 +9,10 @@ StdTypeDef = TypeDef -@jit.unroll_safe -def issubtypedef(a, b): -from pypy.objspace.std.objectobject import W_ObjectObject -if b is W_ObjectObject.typedef: -return True -if a is None: -return False -if a is b: -return True -for a1 in a.bases: -if issubtypedef(a1, b): -return True -return False - std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict, doc="dictionary for instance variables (if defined)") std_dict_descr.name = '__dict__' -# -# -# All the code below fishes from the multimethod registration tables -# the descriptors to put into the W_TypeObjects. -# class TypeCache(SpaceCache): def build(cache, typedef): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -5,7 +5,7 @@ from pypy.interpreter.typedef import weakref_descr, GetSetProperty,\ descr_get_dict from pypy.interpreter.astcompiler.misc import mangle -from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member +from pypy.objspace.std.stdtypedef import std_dict_descr, Member from pypy.objspace.std.stdtypedef import StdTypeDef from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, @@ -907,6 +907,20 @@ w_layout1 = w_layout1.w_same_layout_as or w_layout1 return True +@unroll_safe +def issubtypedef(a, b): +from pypy.objspace.std.objectobject import W_ObjectObject +if b is W_ObjectObject.typedef: +return True +if a is None: +return False +if a is b: +return True +for a1 in a.bases: +if issubtypedef(a1, b): +return True +return False + def find_best_base(space, bases_w): """The best base is one of the bases in the given list: the one whose layout a new type should use as a starting point. ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Remove multimethod option and references to pypy.objspace.std.multimethod.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69447:044f6359573b Date: 2014-02-25 19:55 +0100 http://bitbucket.org/pypy/pypy/changeset/044f6359573b/ Log:Remove multimethod option and references to pypy.objspace.std.multimethod. diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -272,9 +272,6 @@ # weakrefs needed, because of get_subclasses() requires=[("translation.rweakref", True)]), -ChoiceOption("multimethods", "the multimethod implementation to use", - ["doubledispatch", "mrd"], - default="mrd"), BoolOption("withidentitydict", "track types that override __hash__, __eq__ or __cmp__ and use a special dict strategy for those which do not", default=False, diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -54,7 +54,6 @@ .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py -.. _`pypy/objspace/std/multimethod.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/multimethod.py .. _`pypy/objspace/std/objspace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/objspace.py .. _`pypy/objspace/std/proxy_helpers.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/proxy_helpers.py .. _`pypy/objspace/std/proxyobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/proxyobject.py diff --git a/pypy/doc/config/objspace.std.multimethods.txt b/pypy/doc/config/objspace.std.multimethods.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.std.multimethods.txt +++ /dev/null @@ -1,8 +0,0 @@ -Choose the multimethod implementation. - -* ``doubledispatch`` turns - a multimethod call into a sequence of normal method calls. - -* ``mrd`` uses a technique known as Multiple Row Displacement - which precomputes a few compact tables of numbers and - function pointers. diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -194,23 +194,6 @@ from pypy.config.pypyoption import set_pypy_opt_level set_pypy_opt_level(config, translateconfig.opt) -# as of revision 27081, multimethod.py uses the InstallerVersion1 by default -# because it is much faster both to initialize and run on top of CPython. -# The InstallerVersion2 is optimized for making a translator-friendly -# structure for low level backends. However, InstallerVersion1 is still -# preferable for high level backends, so we patch here. - -from pypy.objspace.std import multimethod -if config.objspace.std.multimethods == 'mrd': -assert multimethod.InstallerVersion1.instance_counter == 0,\ - 'The wrong Installer version has already been instatiated' -multimethod.Installer = multimethod.InstallerVersion2 -elif config.objspace.std.multimethods == 'doubledispatch': -# don't rely on the default, set again here -assert multimethod.InstallerVersion2.instance_counter == 0,\ - 'The wrong Installer version has already been instatiated' -multimethod.Installer = multimethod.InstallerVersion1 - def print_help(self, config): self.opt_parser(config).print_help() diff --git a/pypy/tool/pypyjit.py b/pypy/tool/pypyjit.py --- a/pypy/tool/pypyjit.py +++ b/pypy/tool/pypyjit.py @@ -17,7 +17,6 @@ from pypy.objspace.std import Space from rpython.config.translationoption import set_opt_level from pypy.config.pypyoption import get_pypy_config, set_pypy_opt_level -from pypy.objspace.std import multimethod from rpython.rtyper.annlowlevel import llhelper, llstr, hlstr from rpython.rtyper.lltypesystem.rstr import STR from rpython.rtyper.lltypesystem import lltype @@ -42,8 +41,6 @@ # set_pypy_opt_level(config, level='jit') -config.objspace.std.multimethods = 'mrd' -multimethod.Installer = multimethod.InstallerVersion2 print config import sys, pdb ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Remove unnecessary delegation methods.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69449:aa67858b4e18 Date: 2014-02-25 20:26 +0100 http://bitbucket.org/pypy/pypy/changeset/aa67858b4e18/ Log:Remove unnecessary delegation methods. diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py --- a/pypy/objspace/std/smalllongobject.py +++ b/pypy/objspace/std/smalllongobject.py @@ -376,14 +376,6 @@ raise OverflowError("integer multiplication") -def delegate_SmallLong2Float(space, w_small): -return space.newfloat(float(w_small.longlong)) - - -def delegate_SmallLong2Complex(space, w_small): -return space.newcomplex(float(w_small.longlong), 0.0) - - def _int2small(space, w_int): # XXX: W_IntObject.descr_long should probably return W_SmallLongs return W_SmallLongObject.fromint(w_int.int_w(space)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Remove ignore_for_isinstance_cache attributes. The isinstance cache is built explicitly now.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69448:6c758cd93812 Date: 2014-02-25 20:19 +0100 http://bitbucket.org/pypy/pypy/changeset/6c758cd93812/ Log:Remove ignore_for_isinstance_cache attributes. The isinstance cache is built explicitly now. diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1128,8 +1128,6 @@ class W_BaseDictMultiIterObject(W_Root): _immutable_fields_ = ["iteratorimplementation"] -ignore_for_isinstance_cache = True - def __init__(self, space, iteratorimplementation): self.space = space self.iteratorimplementation = iteratorimplementation diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py --- a/pypy/objspace/std/proxyobject.py +++ b/pypy/objspace/std/proxyobject.py @@ -8,8 +8,6 @@ def transparent_class(name, BaseCls): class W_Transparent(BaseCls): -ignore_for_isinstance_cache = True - def __init__(self, space, w_type, w_controller): self.w_type = w_type self.w_controller = w_controller ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Fix cpyext.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69450:fd070a9318e5 Date: 2014-02-25 20:42 +0100 http://bitbucket.org/pypy/pypy/changeset/fd070a9318e5/ Log:Fix cpyext. 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 @@ -312,11 +312,6 @@ @bootstrap_function def init_typeobject(space): -# Probably a hack -space.model.typeorder[W_PyCTypeObject] = [(W_PyCTypeObject, None), - (W_TypeObject, None), - (W_Root, None)] - make_typedescr(space.w_type.instancetypedef, basestruct=PyTypeObject, alloc=type_alloc, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] buildbot default: link the osx64 test results in listing
Author: Brian Kearns Branch: Changeset: r907:8550f84840ee Date: 2014-02-25 19:51 -0500 http://bitbucket.org/pypy/buildbot/changeset/8550f84840ee/ Log:link the osx64 test results in listing diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -38,6 +38,7 @@ 'linux': 'linux-x86-32', 'linux64': 'linux-x86-64', 'osx': 'macosx-x86-32', +'osx64': 'macosx-x86-64', 'win32': 'win-x86-32', } ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy kill-multimethod: Kill pypy.objspace.std.stdtypedef and move TypeCache to pypy.objspace.std.typeobject.
Author: Manuel Jacob Branch: kill-multimethod Changeset: r69451:750998b0ec09 Date: 2014-02-26 04:52 +0100 http://bitbucket.org/pypy/pypy/changeset/750998b0ec09/ Log:Kill pypy.objspace.std.stdtypedef and move TypeCache to pypy.objspace.std.typeobject. diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.objspace.std import stdtypedef, frame, transparent, callmethod +from pypy.objspace.std import frame, transparent, callmethod from pypy.objspace.descroperation import DescrOperation, raiseattrerror from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant from rpython.rlib.debug import make_sure_not_resized @@ -28,7 +28,7 @@ from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject -from pypy.objspace.std.typeobject import W_TypeObject +from pypy.objspace.std.typeobject import W_TypeObject, TypeCache from pypy.objspace.std.unicodeobject import W_UnicodeObject, wrapunicode @@ -118,10 +118,10 @@ return self.gettypeobject(cls.typedef) def gettypeobject(self, typedef): -# stdtypedef.TypeCache maps each StdTypeDef instance to its +# typeobject.TypeCache maps a TypeDef instance to its # unique-for-this-space W_TypeObject instance assert typedef is not None -return self.fromcache(stdtypedef.TypeCache).getorbuild(typedef) +return self.fromcache(TypeCache).getorbuild(typedef) def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py deleted file mode 100644 --- a/pypy/objspace/std/stdtypedef.py +++ /dev/null @@ -1,40 +0,0 @@ -from pypy.interpreter.baseobjspace import SpaceCache - - -class TypeCache(SpaceCache): -def build(cache, typedef): -"NOT_RPYTHON: initialization-time only." -# build a W_TypeObject from this StdTypeDef -from pypy.objspace.std.typeobject import W_TypeObject -from pypy.objspace.std.objectobject import W_ObjectObject - -space = cache.space -w = space.wrap -rawdict = typedef.rawdict -lazyloaders = {} - -# compute the bases -if typedef is W_ObjectObject.typedef: -bases_w = [] -else: -bases = typedef.bases or [W_ObjectObject.typedef] -bases_w = [space.gettypeobject(base) for base in bases] - -# wrap everything -dict_w = {} -for descrname, descrvalue in rawdict.items(): -dict_w[descrname] = w(descrvalue) - -if typedef.applevel_subclasses_base is not None: -overridetypedef = typedef.applevel_subclasses_base.typedef -else: -overridetypedef = typedef -w_type = W_TypeObject(space, typedef.name, bases_w, dict_w, - overridetypedef=overridetypedef) -if typedef is not overridetypedef: -w_type.w_doc = space.wrap(typedef.doc) -w_type.lazyloaders = lazyloaders -return w_type - -def ready(self, w_type): -w_type.ready() diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,5 +1,5 @@ from pypy.interpreter import gateway -from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.baseobjspace import W_Root, SpaceCache from pypy.interpreter.error import oefmt, OperationError from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter.typedef import weakref_descr, GetSetProperty,\ @@ -1203,3 +1203,39 @@ names = [cls.getname(space) for cls in cycle] raise OperationError(space.w_TypeError, space.wrap( "cycle among base classes: " + ' < '.join(names))) + + +class TypeCache(SpaceCache): +def build(self, typedef): +"NOT_RPYTHON: initialization-time only." +from pypy.objspace.std.objectobject import W_ObjectObject + +space = self.space +rawdict = typedef.rawdict +lazyloaders = {} + +# compute the bases +if typedef is W_ObjectObject.typedef: +bases_w = [] +else: +bases = typedef.bases or [W_ObjectObject.typedef] +bases_w = [space.gettypeobject(base) for base in bases] + +# wrap everything +dict_w = {} +for descrname, descrvalue in rawdict.items(): +dict_w[descrname] = space.wrap(descrvalue) + +if typedef.applevel_subclasses_base is not None: +