[pypy-commit] stmgc default: add major collections to test
Author: Remi Meier meier...@student.ethz.ch Branch: Changeset: r325:cf2cf2b3df21 Date: 2013-07-01 08:38 +0200 http://bitbucket.org/pypy/stmgc/changeset/cf2cf2b3df21/ Log:add major collections to test diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -19,6 +19,7 @@ #define PREBUILT 3 // per thread #define MAXROOTS 1000 #define SHARED_ROOTS 5 // shared by threads +#define DO_MAJOR_COLLECTS 1 @@ -276,19 +277,25 @@ gcptr rare_events(gcptr p, gcptr _r, gcptr _sr) { -int k = get_rand(10); -if (k == 1) { +int k = get_rand(100); +if (k 10) { push_roots(); stm_push_root(p); stm_become_inevitable(fun); p = stm_pop_root(); pop_roots(); } -else if (k 4) { +else if (k 40) { push_roots(); stmgc_minor_collect(); pop_roots(); p = NULL; +} else if (k 41 DO_MAJOR_COLLECTS) { +fprintf(stdout, major collect\n); +push_roots(); +stmgcpage_possibly_major_collect(1); +pop_roots(); +p = NULL; } return p; } @@ -418,6 +425,7 @@ k = get_rand(9); check(p); +assert(thread_descriptor-active); if (k 3) p = simple_events(p, _r, _sr); ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: (andrewchambers) merge identity-set. This branch adds a set based on
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65132:1d6d177a0c6e Date: 2013-07-01 08:49 +0200 http://bitbucket.org/pypy/pypy/changeset/1d6d177a0c6e/ Log:(andrewchambers) merge identity-set. This branch adds a set based on identity, just like identity dict. diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -26,7 +26,7 @@ def __repr__(self): representation for debugging purposes reprlist = [repr(w_item) for w_item in self.getkeys()] -return %s(%s) % (self.__class__.__name__, ', '.join(reprlist)) +return %s(%s)(%s) % (self.__class__.__name__, self.strategy, ', '.join(reprlist)) def from_storage_and_strategy(self, storage, strategy): obj = self._newobj(self.space, None) @@ -780,6 +780,8 @@ strategy = self.space.fromcache(StringSetStrategy) elif type(w_key) is W_UnicodeObject: strategy = self.space.fromcache(UnicodeSetStrategy) +elif self.space.type(w_key).compares_by_identity(): +strategy = self.space.fromcache(IdentitySetStrategy) else: strategy = self.space.fromcache(ObjectSetStrategy) w_set.strategy = strategy @@ -1336,6 +1338,41 @@ break d_obj[w_item] = None +class IdentitySetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): +erase, unerase = rerased.new_erasing_pair(identityset) +erase = staticmethod(erase) +unerase = staticmethod(unerase) + +def get_empty_storage(self): +return self.erase({}) + +def get_empty_dict(self): +return {} + +def is_correct_type(self, w_key): +w_type = self.space.type(w_key) +return w_type.compares_by_identity() + +def may_contain_equal_elements(self, strategy): +#empty first, probably more likely +if strategy is self.space.fromcache(EmptySetStrategy): +return False +if strategy is self.space.fromcache(IntegerSetStrategy): +return False +if strategy is self.space.fromcache(StringSetStrategy): +return False +if strategy is self.space.fromcache(UnicodeSetStrategy): +return False +return True + +def unwrap(self, w_item): +return w_item + +def wrap(self, item): +return item + +def iter(self, w_set): +return IdentityIteratorImplementation(self.space, self, w_set) class IteratorImplementation(object): def __init__(self, space, strategy, implementation): @@ -1427,6 +1464,17 @@ else: return None +class IdentityIteratorImplementation(IteratorImplementation): +def __init__(self, space, strategy, w_set): +IteratorImplementation.__init__(self, space, strategy, w_set) +d = strategy.unerase(w_set.sstorage) +self.iterator = d.iterkeys() + +def next_entry(self): +for key in self.iterator: +return self.space.wrap(key) +else: +return None class RDictIteratorImplementation(IteratorImplementation): def __init__(self, space, strategy, w_set): @@ -1545,6 +1593,15 @@ w_set.strategy = space.fromcache(UnicodeSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) return + +# check for compares by identity +for w_item in iterable_w: +if not space.type(w_item).compares_by_identity(): +break +else: +w_set.strategy = space.fromcache(IdentitySetStrategy) +w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) +return w_set.strategy = space.fromcache(ObjectSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) diff --git a/pypy/objspace/std/test/test_identityset.py b/pypy/objspace/std/test/test_identityset.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/std/test/test_identityset.py @@ -0,0 +1,209 @@ +import py + + + +class AppTestIdentitySet(object): + +#needed for compares_by_identity +spaceconfig = {objspace.std.withidentitydict: True} + +def setup_class(cls): +from pypy.objspace.std import identitydict +if cls.runappdirect: +py.test.skip(interp2app doesn't work on appdirect) + +def w_uses_strategy(self, s , obj): +import __pypy__ +return s in __pypy__.internal_repr(obj) + +def test_use_identity_strategy(self): + +class Plain(object): +pass + +class CustomEq(object): +def __eq__(self, other): +return True + +class CustomCmp (object): +def __cmp__(self, other): +return 0 + +class CustomHash(object): +def __hash__(self): +return 0 + +s = set() + +assert not
[pypy-commit] pypy default: document branch
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65133:8c5e26a49209 Date: 2013-07-01 08:50 +0200 http://bitbucket.org/pypy/pypy/changeset/8c5e26a49209/ Log:document branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,5 @@ .. branch: ndarray-view Add view to ndarray and zeroD arrays, not on dtype scalars yet +.. branch: identity-set +Faster sets for objects ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy identity-set: close to-be-merged branch
Author: Maciej Fijalkowski fij...@gmail.com Branch: identity-set Changeset: r65131:bacccee16ef3 Date: 2013-07-01 08:49 +0200 http://bitbucket.org/pypy/pypy/changeset/bacccee16ef3/ Log:close to-be-merged branch ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Some set speedups
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65134:8a241c817172 Date: 2013-07-01 09:14 +0200 http://bitbucket.org/pypy/pypy/changeset/8a241c817172/ Log:Some set speedups diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -941,7 +941,12 @@ def equals(self, w_set, w_other): if w_set.length() != w_other.length(): return False +if w_set.length() == 0: +return True +# it's possible to have 0-lenght strategy that's not empty items = self.unerase(w_set.sstorage).keys() +if not self.may_contain_equal_elements(w_other.strategy): +return False for key in items: if not w_other.has_key(self.wrap(key)): return False @@ -1210,7 +1215,9 @@ def may_contain_equal_elements(self, strategy): if strategy is self.space.fromcache(IntegerSetStrategy): return False -if strategy is self.space.fromcache(EmptySetStrategy): +elif strategy is self.space.fromcache(EmptySetStrategy): +return False +elif strategy is self.space.fromcache(IdentitySetStrategy): return False return True @@ -1244,7 +1251,9 @@ def may_contain_equal_elements(self, strategy): if strategy is self.space.fromcache(IntegerSetStrategy): return False -if strategy is self.space.fromcache(EmptySetStrategy): +elif strategy is self.space.fromcache(EmptySetStrategy): +return False +elif strategy is self.space.fromcache(IdentitySetStrategy): return False return True @@ -1278,9 +1287,11 @@ def may_contain_equal_elements(self, strategy): if strategy is self.space.fromcache(StringSetStrategy): return False -if strategy is self.space.fromcache(UnicodeSetStrategy): +elif strategy is self.space.fromcache(UnicodeSetStrategy): return False -if strategy is self.space.fromcache(EmptySetStrategy): +elif strategy is self.space.fromcache(EmptySetStrategy): +return False +elif strategy is self.space.fromcache(IdentitySetStrategy): return False return True @@ -1342,7 +1353,7 @@ erase, unerase = rerased.new_erasing_pair(identityset) erase = staticmethod(erase) unerase = staticmethod(unerase) - + def get_empty_storage(self): return self.erase({}) @@ -1369,10 +1380,10 @@ return w_item def wrap(self, item): -return item - +return item + def iter(self, w_set): -return IdentityIteratorImplementation(self.space, self, w_set) +return IdentityIteratorImplementation(self.space, self, w_set) class IteratorImplementation(object): def __init__(self, space, strategy, implementation): @@ -1593,7 +1604,7 @@ w_set.strategy = space.fromcache(UnicodeSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) return - + # check for compares by identity for w_item in iterable_w: if not space.type(w_item).compares_by_identity(): @@ -1601,7 +1612,7 @@ else: w_set.strategy = space.fromcache(IdentitySetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) -return +return w_set.strategy = space.fromcache(ObjectSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: fix uninitialized shadowstack problem during major collection
Author: Remi Meier meier...@student.ethz.ch Branch: Changeset: r326:18b8edd35778 Date: 2013-07-01 11:18 +0200 http://bitbucket.org/pypy/stmgc/changeset/18b8edd35778/ Log:fix uninitialized shadowstack problem during major collection diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1504,7 +1504,6 @@ revision_t i; struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor)); memset(d, 0, sizeof(struct tx_descriptor)); - stmgcpage_acquire_global_lock(); struct tx_public_descriptor *pd; i = descriptor_array_free_list; @@ -1554,7 +1553,6 @@ (long)d-public_descriptor_index, (long)pthread_self())); stmgcpage_init_tls(); - stmgcpage_release_global_lock(); return 1; } else @@ -1567,7 +1565,6 @@ struct tx_descriptor *d = thread_descriptor; assert(d != NULL); assert(d-active == 0); -stmgcpage_acquire_global_lock(); /* our nursery is empty at this point. The list 'stolen_objects' should have been emptied at the previous minor collection and @@ -1585,7 +1582,6 @@ if (d-tx_prev != NULL) d-tx_prev-tx_next = d-tx_next; if (d-tx_next != NULL) d-tx_next-tx_prev = d-tx_prev; if (d == stm_tx_head) stm_tx_head = d-tx_next; -stmgcpage_release_global_lock(); thread_descriptor = NULL; diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -625,6 +625,7 @@ if (d != saved) { /* Hack: temporarily pretend that we are the other thread... */ +assert(d-shadowstack_end_ref *d-shadowstack_end_ref); thread_descriptor = d; stm_private_rev_num = *d-private_revision_ref; stm_read_barrier_cache = *d-read_barrier_cache_ref; diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -198,7 +198,8 @@ return (revision_t)p; } - +/* XXX: think about if p-h_original needs a volatile read + and if we need a memory fence (smp_wmb())... */ spinlock_acquire(d-public_descriptor-collection_lock, 'I'); /* old objects must have an h_original xOR be diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -79,12 +79,14 @@ void stm_initialize(void) { +stmgcpage_acquire_global_lock(); int r = DescriptorInit(); if (r != 1) stm_fatalerror(stm_initialize: DescriptorInit failure\n); stmgc_init_nursery(); init_shadowstack(); //stmgcpage_init_tls(); +stmgcpage_release_global_lock(); BeginInevitableTransaction(); } @@ -92,10 +94,12 @@ { stmgc_minor_collect(); /* force everything out of the nursery */ CommitTransaction(); +stmgcpage_acquire_global_lock(); //stmgcpage_done_tls(); done_shadowstack(); stmgc_done_nursery(); DescriptorDone(); +stmgcpage_release_global_lock(); } // ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: Add asserts
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r327:07c9a1daeba2 Date: 2013-07-01 11:47 +0200 http://bitbucket.org/pypy/stmgc/changeset/07c9a1daeba2/ Log:Add asserts diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -269,6 +269,7 @@ else { assert(obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); gcptr B = (gcptr)obj-h_revision; +assert(!(B-h_tid GCFLAG_STUB)); gcptrlist_insert(objects_to_trace, B); if (!(B-h_tid GCFLAG_PUBLIC)) { @@ -286,6 +287,7 @@ } } obj-h_tid |= GCFLAG_VISITED; +assert(!(obj-h_tid GCFLAG_STUB)); gcptrlist_insert(objects_to_trace, obj); } ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: add atomic transactions in demo_random
Author: Remi Meier meier...@student.ethz.ch Branch: Changeset: r328:6eac0903bcb9 Date: 2013-07-01 12:32 +0200 http://bitbucket.org/pypy/stmgc/changeset/6eac0903bcb9/ Log:add atomic transactions in demo_random diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -60,6 +60,7 @@ int num_roots_outside_perform; int steps_left; int interruptible; +int atomic; }; __thread struct thread_data td; @@ -74,6 +75,24 @@ (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); } +static void inc_atomic() +{ +assert(td.interruptible); +assert(stm_atomic(0) == td.atomic); +td.atomic++; +stm_atomic(1); +assert(stm_atomic(0) == td.atomic); +} + +static void dec_atomic() +{ +assert(td.interruptible); +assert(stm_atomic(0) == td.atomic); +td.atomic--; +stm_atomic(-1); +assert(stm_atomic(0) == td.atomic); +} + int get_rand(int max) { return (int)(rand_r(td.thread_seed) % (unsigned int)max); @@ -254,7 +273,8 @@ td.thread_seed = default_seed++; td.steps_left = STEPS_PER_THREAD; td.interruptible = 0; - +td.atomic = 0; + td.num_roots = PREBUILT + NUMROOTS; for (i = 0; i PREBUILT; i++) { if (i % 3 == 0) { @@ -303,7 +323,7 @@ gcptr simple_events(gcptr p, gcptr _r, gcptr _sr) { nodeptr w_r; -int k = get_rand(8); +int k = get_rand(11); int num = get_rand(td.num_roots); switch (k) { case 0: // remove a root @@ -338,6 +358,18 @@ check(p); w_r-next = (struct node*)p; break; +case 8: +if (td.interruptible) { +inc_atomic(); +} +break; +case 9: +case 10: +/* more likely to be less atomic */ +if (td.atomic) { +dec_atomic(); +} +break; } return p; } @@ -469,7 +501,7 @@ td.num_roots = td.num_roots_outside_perform; // done overwritten by the following pop_roots(): // copy_roots(td.roots_outside_perform, td.roots, td.num_roots); - +td.atomic = 0; // may be set differently on abort // refresh td.roots: gcptr end_marker = stm_pop_root(); assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF); @@ -490,14 +522,26 @@ int run_me() { gcptr p = NULL; -while (td.steps_left--0) { +while (td.steps_left--0 || td.atomic) { if (td.steps_left % 8 == 0) fprintf(stdout, #); p = do_step(p); -if (p == (gcptr)-1) -return -1; +if (p == (gcptr)-1) { +if (td.atomic) { +// can't break, well, we could return to perform_transaction +// while being atomic. (TODO) +// may be true when major gc requested: +// assert(stm_should_break_transaction() == 0); +assert(stm_atomic(0) == td.atomic); +p = NULL; +} +else { +assert(stm_atomic(0) == 0); +return -1; +} +} } return 0; } diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -906,6 +906,8 @@ long stm_atomic(long delta) { struct tx_descriptor *d = thread_descriptor; + if (delta) // no atomic-checks +dprintf((stm_atomic(%lu)\n, delta)); d-atomic += delta; assert(d-atomic = 0); update_reads_size_limit(d); diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -198,9 +198,6 @@ return (revision_t)p; } -/* XXX: think about if p-h_original needs a volatile read - and if we need a memory fence (smp_wmb())... */ - spinlock_acquire(d-public_descriptor-collection_lock, 'I'); /* old objects must have an h_original xOR be the original itself. @@ -222,7 +219,6 @@ gcptr O = stmgc_duplicate_old(p); p-h_original = (revision_t)O; p-h_tid |= GCFLAG_HAS_ID; -O-h_tid |= GCFLAG_PUBLIC; if (p-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)p-h_revision; ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: Avoids doing this (I fixed the nursery to always really be null-allocated)
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r329:5b45c01aa560 Date: 2013-07-01 12:29 +0200 http://bitbucket.org/pypy/stmgc/changeset/5b45c01aa560/ Log:Avoids doing this (I fixed the nursery to always really be null- allocated) diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -91,7 +91,7 @@ assert(tid == (tid STM_USER_TID_MASK)); gcptr P = allocate_nursery(size, tid); P-h_revision = stm_private_rev_num; -P-h_original = 0; +/*P-h_original = 0; --- the object is null-initialized already */ return P; } ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: merge heads
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r330:bf175ef919bf Date: 2013-07-01 12:38 +0200 http://bitbucket.org/pypy/stmgc/changeset/bf175ef919bf/ Log:merge heads diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -60,6 +60,7 @@ int num_roots_outside_perform; int steps_left; int interruptible; +int atomic; }; __thread struct thread_data td; @@ -74,6 +75,24 @@ (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); } +static void inc_atomic() +{ +assert(td.interruptible); +assert(stm_atomic(0) == td.atomic); +td.atomic++; +stm_atomic(1); +assert(stm_atomic(0) == td.atomic); +} + +static void dec_atomic() +{ +assert(td.interruptible); +assert(stm_atomic(0) == td.atomic); +td.atomic--; +stm_atomic(-1); +assert(stm_atomic(0) == td.atomic); +} + int get_rand(int max) { return (int)(rand_r(td.thread_seed) % (unsigned int)max); @@ -254,7 +273,8 @@ td.thread_seed = default_seed++; td.steps_left = STEPS_PER_THREAD; td.interruptible = 0; - +td.atomic = 0; + td.num_roots = PREBUILT + NUMROOTS; for (i = 0; i PREBUILT; i++) { if (i % 3 == 0) { @@ -303,7 +323,7 @@ gcptr simple_events(gcptr p, gcptr _r, gcptr _sr) { nodeptr w_r; -int k = get_rand(8); +int k = get_rand(11); int num = get_rand(td.num_roots); switch (k) { case 0: // remove a root @@ -338,6 +358,18 @@ check(p); w_r-next = (struct node*)p; break; +case 8: +if (td.interruptible) { +inc_atomic(); +} +break; +case 9: +case 10: +/* more likely to be less atomic */ +if (td.atomic) { +dec_atomic(); +} +break; } return p; } @@ -469,7 +501,7 @@ td.num_roots = td.num_roots_outside_perform; // done overwritten by the following pop_roots(): // copy_roots(td.roots_outside_perform, td.roots, td.num_roots); - +td.atomic = 0; // may be set differently on abort // refresh td.roots: gcptr end_marker = stm_pop_root(); assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF); @@ -490,14 +522,26 @@ int run_me() { gcptr p = NULL; -while (td.steps_left--0) { +while (td.steps_left--0 || td.atomic) { if (td.steps_left % 8 == 0) fprintf(stdout, #); p = do_step(p); -if (p == (gcptr)-1) -return -1; +if (p == (gcptr)-1) { +if (td.atomic) { +// can't break, well, we could return to perform_transaction +// while being atomic. (TODO) +// may be true when major gc requested: +// assert(stm_should_break_transaction() == 0); +assert(stm_atomic(0) == td.atomic); +p = NULL; +} +else { +assert(stm_atomic(0) == 0); +return -1; +} +} } return 0; } diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -906,6 +906,8 @@ long stm_atomic(long delta) { struct tx_descriptor *d = thread_descriptor; + if (delta) // no atomic-checks +dprintf((stm_atomic(%lu)\n, delta)); d-atomic += delta; assert(d-atomic = 0); update_reads_size_limit(d); diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -198,9 +198,6 @@ return (revision_t)p; } -/* XXX: think about if p-h_original needs a volatile read - and if we need a memory fence (smp_wmb())... */ - spinlock_acquire(d-public_descriptor-collection_lock, 'I'); /* old objects must have an h_original xOR be the original itself. @@ -222,7 +219,6 @@ gcptr O = stmgc_duplicate_old(p); p-h_original = (revision_t)O; p-h_tid |= GCFLAG_HAS_ID; -O-h_tid |= GCFLAG_PUBLIC; if (p-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)p-h_revision; ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: Fix(?) the logic, I believe, and remove the recursion; but demo_random
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r331:452c22b17f3e Date: 2013-07-01 12:52 +0200 http://bitbucket.org/pypy/stmgc/changeset/452c22b17f3e/ Log:Fix(?) the logic, I believe, and remove the recursion; but demo_random crashes. To investigate. diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -230,6 +230,10 @@ if (obj-h_revision 1) { assert(!(obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED)); obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE; /* see also fix_outdated() */ + +obj-h_tid |= GCFLAG_VISITED; +assert(!(obj-h_tid GCFLAG_STUB)); +gcptrlist_insert(objects_to_trace, obj); } else if (obj-h_tid GCFLAG_PUBLIC) { /* h_revision is a ptr: we have a more recent version */ @@ -269,26 +273,24 @@ else { assert(obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); gcptr B = (gcptr)obj-h_revision; +assert(B-h_tid (GCFLAG_PUBLIC | GCFLAG_BACKUP_COPY)); + +obj-h_tid |= GCFLAG_VISITED; +B-h_tid |= GCFLAG_VISITED; +assert(!(obj-h_tid GCFLAG_STUB)); assert(!(B-h_tid GCFLAG_STUB)); -gcptrlist_insert(objects_to_trace, B); +gcptrlist_insert2(objects_to_trace, obj, B); -if (!(B-h_tid GCFLAG_PUBLIC)) { -/* a regular private_from_protected object with a backup copy B */ -assert(B-h_tid GCFLAG_BACKUP_COPY); -assert(B-h_revision 1); -B-h_tid |= GCFLAG_VISITED; -} -else { -/* a private_from_protected with a stolen backup copy B */ +if (IS_POINTER(B-h_revision)) { +assert(B-h_tid GCFLAG_PUBLIC); assert(!(B-h_tid GCFLAG_BACKUP_COPY)); -gcptr obj1 = B; -visit(obj1); /* xxx recursion? */ -obj-h_revision = (revision_t)obj1; +assert(!(B-h_revision 2)); + +pobj = (gcptr *)B-h_revision; +obj = *pobj; +goto restart; } } -obj-h_tid |= GCFLAG_VISITED; -assert(!(obj-h_tid GCFLAG_STUB)); -gcptrlist_insert(objects_to_trace, obj); } static void visit_all_objects(void) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: More fixes
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r332:874251ce1920 Date: 2013-07-01 13:04 +0200 http://bitbucket.org/pypy/stmgc/changeset/874251ce1920/ Log:More fixes diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -219,21 +219,14 @@ return; restart: -if (obj-h_tid GCFLAG_VISITED) { -dprintf(([already visited: %p]\n, obj)); -assert(obj == *pobj); -assert((obj-h_revision 3) || /* either odd, or stub */ - (obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED)); -return;/* already seen */ -} - if (obj-h_revision 1) { assert(!(obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED)); -obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE; /* see also fix_outdated() */ - -obj-h_tid |= GCFLAG_VISITED; assert(!(obj-h_tid GCFLAG_STUB)); -gcptrlist_insert(objects_to_trace, obj); +if (!(obj-h_tid GCFLAG_VISITED)) { +obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE; /* see fix_outdated() */ +obj-h_tid |= GCFLAG_VISITED; +gcptrlist_insert(objects_to_trace, obj); +} } else if (obj-h_tid GCFLAG_PUBLIC) { /* h_revision is a ptr: we have a more recent version */ @@ -270,6 +263,13 @@ *pobj = obj; goto restart; } +else if (obj-h_tid GCFLAG_VISITED) { +dprintf(([already visited: %p]\n, obj)); +assert(obj == *pobj); +assert((obj-h_revision 3) || /* either odd, or stub */ + (obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED)); +return;/* already seen */ +} else { assert(obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); gcptr B = (gcptr)obj-h_revision; diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -91,7 +91,7 @@ assert(tid == (tid STM_USER_TID_MASK)); gcptr P = allocate_nursery(size, tid); P-h_revision = stm_private_rev_num; -/*P-h_original = 0; --- the object is null-initialized already */ +assert(P-h_original == 0); /* null-initialized already */ return P; } ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: in-progress
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r333:e58e43f88445 Date: 2013-07-01 14:44 +0200 http://bitbucket.org/pypy/stmgc/changeset/e58e43f88445/ Log:in-progress diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -764,20 +764,24 @@ long long elapsed_time; /* acquire the lock, but don't double-acquire it if already committing */ - if (d-public_descriptor-collection_lock != 'C') { -spinlock_acquire(d-public_descriptor-collection_lock, 'C'); -if (d-public_descriptor-stolen_objects.size != 0) - stm_normalize_stolen_objects(d); - } - + if (d-public_descriptor-collection_lock != 'C') +{ + spinlock_acquire(d-public_descriptor-collection_lock, 'C'); + if (d-public_descriptor-stolen_objects.size != 0) +stm_normalize_stolen_objects(d); + assert(!stm_has_got_any_lock(d)); +} + else +{ + CancelLocks(d); + assert(!stm_has_got_any_lock(d)); +} assert(d-active != 0); assert(!is_inevitable(d)); assert(num ABORT_REASONS); d-num_aborts[num]++; - CancelLocks(d); - /* compute the elapsed time */ if (d-start_real_time.tv_nsec != -1 clock_gettime(CLOCK_MONOTONIC, now) = 0) { @@ -954,6 +958,7 @@ revision_t my_lock = d-my_lock; wlog_t *item; + assert(!stm_has_got_any_lock(d)); assert(d-public_descriptor-stolen_objects.size == 0); if (!g2l_any_entry(d-public_to_private)) @@ -1032,6 +1037,46 @@ } G2L_LOOP_END; } +_Bool stm_has_got_any_lock(struct tx_descriptor *d) +{ + wlog_t *item; + int found_locked, found_unlocked; + + if (!g2l_any_entry(d-public_to_private)) +return 0; + + found_locked = 0; + found_unlocked = 0; + + G2L_LOOP_FORWARD(d-public_to_private, item) +{ + gcptr R = item-addr; + gcptr L = item-val; + if (L == NULL) +continue; + + revision_t expected, v = L-h_revision; + + if (L-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) +expected = (revision_t)R; + else +expected = *d-private_revision_ref; + + if (v == expected) +{ + assert(R-h_revision != d-my_lock); + found_unlocked = 1; + continue; +} + + found_locked = 1; + assert(found_unlocked == 0); /* an unlocked followed by a locked: no */ + +} G2L_LOOP_END; + + return found_locked; +} + static pthread_mutex_t mutex_prebuilt_gcroots = PTHREAD_MUTEX_INITIALIZER; static void UpdateChainHeads(struct tx_descriptor *d, revision_t cur_time, diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -190,6 +190,7 @@ gcptr stm_get_read_obj(long); /* debugging */ void stm_clear_read_cache(void); /* debugging */ void _stm_test_forget_previous_state(void); /* debugging */ +_Bool stm_has_got_any_lock(struct tx_descriptor *); struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *); int DescriptorInit(void); diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -346,6 +346,7 @@ { struct tx_descriptor *d; for (d = stm_tx_head; d; d = d-tx_next) { +assert(!stm_has_got_any_lock(d)); /* the roots pushed on the shadowstack */ mark_roots(d-shadowstack, *d-shadowstack_end_ref); @@ -356,15 +357,24 @@ /* the current transaction's private copies of public objects */ wlog_t *item; +struct G2L new_public_to_private; +memset(new_public_to_private, 0, sizeof(new_public_to_private)); + G2L_LOOP_FORWARD(d-public_to_private, item) { /* note that 'item-addr' is also in the read set, so if it was outdated, it will be found at that time */ -visit(item-addr); -visit(item-val); +gcptr key = item-addr; +gcptr val = item-val; +visit(key); +visit(val); +g2l_insert(new_public_to_private, key, val); } G2L_LOOP_END; +g2l_delete_not_used_any_more(d-public_to_private); +d-public_to_private = new_public_to_private; + /* make sure that the other lists are empty */ assert(gcptrlist_size(d-public_with_young_copy) == 0); assert(gcptrlist_size(d-public_descriptor-stolen_objects) == 0); @@ -587,6 +597,7 @@ struct tx_descriptor *d; for (d = stm_tx_head; d; d = d-tx_next) { free_unused_local_pages(d-public_descriptor); +assert(!stm_has_got_any_lock(d)); } } diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -536,6 +536,7 @@ { dprintf((minor collection [%p to %p]\n, d-nursery_base, d-nursery_end)); +assert(!stm_has_got_any_lock(d)); /* acquire the collection lock first */ setup_minor_collect(d); @@ -562,6 +563,7 @@ with GCFLAG_OLD */ teardown_minor_collect(d); +assert(!stm_has_got_any_lock(d)); /* When doing minor collections with the nursery mostly empty, as occurs when other threads force major
[pypy-commit] stmgc default: in-progress
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r334:345ed0d7dc64 Date: 2013-07-01 15:02 +0200 http://bitbucket.org/pypy/stmgc/changeset/345ed0d7dc64/ Log:in-progress diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -293,6 +293,20 @@ } } +static void visit_keep(gcptr obj) +{ +if (!(obj-h_tid GCFLAG_VISITED)) { +obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE; /* see fix_outdated() */ +obj-h_tid |= GCFLAG_VISITED; +gcptrlist_insert(objects_to_trace, obj); + +if (IS_POINTER(obj-h_revision)) { +assert(!(obj-h_revision 2)); +visit((gcptr *)obj-h_revision); +} +} +} + static void visit_all_objects(void) { while (gcptrlist_size(objects_to_trace) 0) { @@ -316,7 +330,6 @@ for (; pobj != pend; pobj++) { obj = *pobj; assert(obj-h_tid GCFLAG_PREBUILT_ORIGINAL); -obj-h_tid = ~GCFLAG_VISITED; assert(IS_POINTER(obj-h_revision)); visit((gcptr *)obj-h_revision); } @@ -357,24 +370,14 @@ /* the current transaction's private copies of public objects */ wlog_t *item; -struct G2L new_public_to_private; -memset(new_public_to_private, 0, sizeof(new_public_to_private)); - G2L_LOOP_FORWARD(d-public_to_private, item) { - /* note that 'item-addr' is also in the read set, so if it was outdated, it will be found at that time */ -gcptr key = item-addr; -gcptr val = item-val; -visit(key); -visit(val); -g2l_insert(new_public_to_private, key, val); - +visit_keep(item-addr); +if (item-val != NULL) +visit_keep(item-val); } G2L_LOOP_END; -g2l_delete_not_used_any_more(d-public_to_private); -d-public_to_private = new_public_to_private; - /* make sure that the other lists are empty */ assert(gcptrlist_size(d-public_with_young_copy) == 0); assert(gcptrlist_size(d-public_descriptor-stolen_objects) == 0); ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: Fix: we must explicitly keep the property that L-h_revision==R that
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r335:bf56c12295c8 Date: 2013-07-01 15:07 +0200 http://bitbucket.org/pypy/stmgc/changeset/bf56c12295c8/ Log:Fix: we must explicitly keep the property that L-h_revision==R that some pairs in public_to_private have got. diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -373,9 +373,20 @@ G2L_LOOP_FORWARD(d-public_to_private, item) { /* note that 'item-addr' is also in the read set, so if it was outdated, it will be found at that time */ -visit_keep(item-addr); -if (item-val != NULL) -visit_keep(item-val); +gcptr R = item-addr; +gcptr L = item-val; +visit_keep(R); +if (L != NULL) { +revision_t v = L-h_revision; +visit_keep(L); +/* a bit of custom logic here: if L-h_revision used to + point exactly to R, as set by stealing, then we must + keep this property, even though visit_keep(L) might + decide it would be better to make it point to a more + recent copy. */ +if (v == (revision_t)R) +L-h_revision = v; /* restore */ +} } G2L_LOOP_END; /* make sure that the other lists are empty */ ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c4: import stmgc/bf56c12295c8
Author: Armin Rigo ar...@tunes.org Branch: stmgc-c4 Changeset: r65135:12aa03d05cb3 Date: 2013-07-01 15:12 +0200 http://bitbucket.org/pypy/pypy/changeset/12aa03d05cb3/ Log:import stmgc/bf56c12295c8 diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -765,20 +765,24 @@ long long elapsed_time; /* acquire the lock, but don't double-acquire it if already committing */ - if (d-public_descriptor-collection_lock != 'C') { -spinlock_acquire(d-public_descriptor-collection_lock, 'C'); -if (d-public_descriptor-stolen_objects.size != 0) - stm_normalize_stolen_objects(d); - } - + if (d-public_descriptor-collection_lock != 'C') +{ + spinlock_acquire(d-public_descriptor-collection_lock, 'C'); + if (d-public_descriptor-stolen_objects.size != 0) +stm_normalize_stolen_objects(d); + assert(!stm_has_got_any_lock(d)); +} + else +{ + CancelLocks(d); + assert(!stm_has_got_any_lock(d)); +} assert(d-active != 0); assert(!is_inevitable(d)); assert(num ABORT_REASONS); d-num_aborts[num]++; - CancelLocks(d); - /* compute the elapsed time */ if (d-start_real_time.tv_nsec != -1 clock_gettime(CLOCK_MONOTONIC, now) = 0) { @@ -907,6 +911,8 @@ long stm_atomic(long delta) { struct tx_descriptor *d = thread_descriptor; + if (delta) // no atomic-checks +dprintf((stm_atomic(%lu)\n, delta)); d-atomic += delta; assert(d-atomic = 0); update_reads_size_limit(d); @@ -953,6 +959,7 @@ revision_t my_lock = d-my_lock; wlog_t *item; + assert(!stm_has_got_any_lock(d)); assert(d-public_descriptor-stolen_objects.size == 0); if (!g2l_any_entry(d-public_to_private)) @@ -1031,6 +1038,46 @@ } G2L_LOOP_END; } +_Bool stm_has_got_any_lock(struct tx_descriptor *d) +{ + wlog_t *item; + int found_locked, found_unlocked; + + if (!g2l_any_entry(d-public_to_private)) +return 0; + + found_locked = 0; + found_unlocked = 0; + + G2L_LOOP_FORWARD(d-public_to_private, item) +{ + gcptr R = item-addr; + gcptr L = item-val; + if (L == NULL) +continue; + + revision_t expected, v = L-h_revision; + + if (L-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) +expected = (revision_t)R; + else +expected = *d-private_revision_ref; + + if (v == expected) +{ + assert(R-h_revision != d-my_lock); + found_unlocked = 1; + continue; +} + + found_locked = 1; + assert(found_unlocked == 0); /* an unlocked followed by a locked: no */ + +} G2L_LOOP_END; + + return found_locked; +} + static pthread_mutex_t mutex_prebuilt_gcroots = PTHREAD_MUTEX_INITIALIZER; static void UpdateChainHeads(struct tx_descriptor *d, revision_t cur_time, @@ -1505,7 +1552,6 @@ revision_t i; struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor)); memset(d, 0, sizeof(struct tx_descriptor)); - stmgcpage_acquire_global_lock(); struct tx_public_descriptor *pd; i = descriptor_array_free_list; @@ -1555,7 +1601,6 @@ (long)d-public_descriptor_index, (long)pthread_self())); stmgcpage_init_tls(); - stmgcpage_release_global_lock(); return 1; } else @@ -1568,7 +1613,6 @@ struct tx_descriptor *d = thread_descriptor; assert(d != NULL); assert(d-active == 0); -stmgcpage_acquire_global_lock(); /* our nursery is empty at this point. The list 'stolen_objects' should have been emptied at the previous minor collection and @@ -1586,7 +1630,6 @@ if (d-tx_prev != NULL) d-tx_prev-tx_next = d-tx_next; if (d-tx_next != NULL) d-tx_next-tx_prev = d-tx_prev; if (d == stm_tx_head) stm_tx_head = d-tx_next; -stmgcpage_release_global_lock(); thread_descriptor = NULL; diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -191,6 +191,7 @@ gcptr stm_get_read_obj(long); /* debugging */ void stm_clear_read_cache(void); /* debugging */ void _stm_test_forget_previous_state(void); /* debugging */ +_Bool stm_has_got_any_lock(struct tx_descriptor *); struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *); int DescriptorInit(void); diff --git a/rpython/translator/stm/src_stm/gcpage.c b/rpython/translator/stm/src_stm/gcpage.c --- a/rpython/translator/stm/src_stm/gcpage.c +++ b/rpython/translator/stm/src_stm/gcpage.c @@ -220,17 +220,14 @@ return; restart: -if (obj-h_tid GCFLAG_VISITED) { -dprintf(([already visited: %p]\n, obj)); -assert(obj == *pobj); -assert((obj-h_revision 3) || /* either odd, or stub */ - (obj-h_tid GCFLAG_PRIVATE_FROM_PROTECTED)); -return;/* already seen */ -} - if
[pypy-commit] pypy default: a fast path for set equality (note that if len(s1) == len(s2), then s1.issubset(s2) - s1 == s2)
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65136:588a9d71f1d6 Date: 2013-07-01 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/588a9d71f1d6/ Log:a fast path for set equality (note that if len(s1) == len(s2), then s1.issubset(s2) - s1 == s2) diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -944,9 +944,11 @@ if w_set.length() == 0: return True # it's possible to have 0-lenght strategy that's not empty -items = self.unerase(w_set.sstorage).keys() +if w_set.strategy is w_other.strategy: +return self._issubset_unwrapped(w_set, w_other) if not self.may_contain_equal_elements(w_other.strategy): return False +items = self.unerase(w_set.sstorage).keys() for key in items: if not w_other.has_key(self.wrap(key)): return False ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c4: Enough to have test_targetdemo compile (but not run yet).
Author: Armin Rigo ar...@tunes.org Branch: stmgc-c4 Changeset: r65137:aef695dc9da1 Date: 2013-07-01 15:35 +0200 http://bitbucket.org/pypy/pypy/changeset/aef695dc9da1/ Log:Enough to have test_targetdemo compile (but not run yet). diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -1,5 +1,5 @@ from rpython.rlib.objectmodel import we_are_translated, specialize -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.extregistry import ExtRegistryEntry @@ -37,73 +37,48 @@ stmgcintf.StmOperations.abort_and_retry() def before_external_call(): -if not is_atomic(): -e = get_errno() -llop.stm_stop_transaction(lltype.Void) -stmgcintf.StmOperations.commit_transaction() -set_errno(e) +llop.stm_commit_transaction(lltype.Void) before_external_call._dont_reach_me_in_del_ = True before_external_call._transaction_break_ = True def after_external_call(): -if not is_atomic(): -e = get_errno() -stmgcintf.StmOperations.begin_inevitable_transaction() -llop.stm_start_transaction(lltype.Void) -set_errno(e) +llop.stm_begin_inevitable_transaction(lltype.Void) after_external_call._dont_reach_me_in_del_ = True after_external_call._transaction_break_ = True def enter_callback_call(): -token = stmgcintf.StmOperations.descriptor_init() -if token != 1: -after_external_call() -else: -ll_assert(not is_atomic(), new thread: is_atomic() != 0) -stmgcintf.StmOperations.begin_inevitable_transaction() -# the StmGCTLS is not built yet. leave it to gc_thread_start() -return token +# XXX assumes that we're not called in a fresh new thread +llop.stm_begin_inevitable_transaction(lltype.Void) +return 0 enter_callback_call._dont_reach_me_in_del_ = True enter_callback_call._transaction_break_ = True -def leave_callback_call(token): -if token != 1: -before_external_call() -else: -# the StmGCTLS is already destroyed, done by gc_thread_die() -# (we don't care if is_atomic() or not, we'll commit now) -stmgcintf.StmOperations.commit_transaction() -stmgcintf.StmOperations.descriptor_done() +def leave_callback_call(ignored): +llop.stm_commit_transaction(lltype.Void) leave_callback_call._dont_reach_me_in_del_ = True leave_callback_call._transaction_break_ = True # def make_perform_transaction(func, CONTAINERP): +from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr +from rpython.translator.stm.stmgcintf import CALLBACK_TX # def _stm_callback(llcontainer, retry_counter): -if not is_atomic(): -llop.stm_start_transaction(lltype.Void) llcontainer = rffi.cast(CONTAINERP, llcontainer) +retry_counter = rffi.cast(lltype.Signed, retry_counter) try: res = func(llcontainer, retry_counter) except Exception, e: -res = 0 # stop perform_transaction() and returns +res = 0 # ends perform_transaction() and returns lle = cast_instance_to_base_ptr(e) llcontainer.got_exception = lle -if not is_atomic(): -llop.stm_stop_transaction(lltype.Void) -return res +return rffi.cast(rffi.INT_real, res) # def perform_transaction(llcontainer): -before_external_call() -adr_of_top = llop.gc_adr_of_root_stack_top(llmemory.Address) -llcallback = llhelper(stmgcintf.StmOperations.CALLBACK_TX, - _stm_callback) -stmgcintf.StmOperations.perform_transaction(llcallback, llcontainer, -adr_of_top) -after_external_call() -keepalive_until_here(llcontainer) +llcallback = llhelper(CALLBACK_TX, _stm_callback) +llop.stm_perform_transaction(lltype.Void, llcontainer, llcallback) perform_transaction._transaction_break_ = True # return perform_transaction diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -440,6 +440,7 @@ 'stm_set_transaction_length': LLOp(), 'stm_change_atomic': LLOp(), 'stm_get_atomic': LLOp(sideeffects=False), +'stm_perform_transaction':LLOp(), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(), diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -603,6 +603,7 @@ OP_STM_GET_ATOMIC =
[pypy-commit] pypy ndarray-ptp: implemented put and array.put
Author: Andrews Medina andrewsmed...@gmail.com Branch: ndarray-ptp Changeset: r65138:a73ce1bfeeab Date: 2013-06-27 00:06 -0300 http://bitbucket.org/pypy/pypy/changeset/a73ce1bfeeab/ Log:implemented put and array.put diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -183,6 +183,7 @@ appleveldefs = {} interpleveldefs = { 'choose': 'interp_arrayops.choose', +'put': 'interp_arrayops.put', 'repeat': 'interp_arrayops.repeat', } submodules = { diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -192,6 +192,45 @@ loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) return out + +@unwrap_spec(mode=str) +def put(space, w_arr, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w +arr = convert_to_array(space, w_arr) +if mode not in constants.MODES: +raise OperationError(space.w_ValueError, + space.wrap(mode %s not known % (mode,))) +indices = convert_to_array(space, w_indices) +values = convert_to_array(space, w_values) +if not indices: +raise OperationError(space.w_ValueError, + space.wrap(indice list cannot be empty)) +if not values: +raise OperationError(space.w_ValueError, + space.wrap(value list cannot be empty)) +dtype = arr.get_dtype() +val_iter = values.create_iter() +ind_iter = indices.create_iter() +while not ind_iter.done(): +index = int_w(space, ind_iter.getitem()) +if index 0 or index = arr.get_size(): +if constants.MODES[mode] == constants.MODE_RAISE: +raise OperationError(space.w_ValueError, space.wrap( +invalid entry in choice array)) +elif constants.MODES[mode] == constants.MODE_WRAP: +index = index % arr.get_size() +else: +assert constants.MODES[mode] == constants.MODE_CLIP +if index 0: +index = 0 +else: +index = arr.get_size() - 1 +arr.setitem(space, [index], val_iter.getitem().convert_to(dtype)) +ind_iter.next() +val_iter.next() + + def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) 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 @@ -550,9 +550,10 @@ raise OperationError(space.w_NotImplementedError, space.wrap( ptp (peak to peak) not implemented yet)) -def descr_put(self, space, w_indices, w_values, w_mode='raise'): -raise OperationError(space.w_NotImplementedError, space.wrap( -put not implemented yet)) +@unwrap_spec(mode=str) +def descr_put(self, space, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy.interp_arrayops import put +put(space, self, w_indices, w_values, mode) def descr_resize(self, space, w_new_shape, w_refcheck=True): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -939,6 +940,7 @@ prod = interp2app(W_NDimArray.descr_prod), max = interp2app(W_NDimArray.descr_max), min = interp2app(W_NDimArray.descr_min), +put = interp2app(W_NDimArray.descr_put), argmax = interp2app(W_NDimArray.descr_argmax), argmin = interp2app(W_NDimArray.descr_argmin), all = interp2app(W_NDimArray.descr_all), diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -132,3 +132,20 @@ x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) assert r.dtype == 'i2' + +def test_put_basic(self): +from numpypy import arange, array +a = arange(5) +a.put([0,2], [-44, -55]) +assert (a == array([-44, 1, -55, 3, 4])).all() + +def test_put_modes(self): +from numpypy import array, arange +a = arange(5) +a.put(22, -5, mode='clip') +assert (a == array([0, 1, 2, 3, -5])).all() +a = arange(5) +a.put(22, -5, mode='wrap') +assert (a == array([0, 1, -5, 3, 4])).all() +raises(ValueError, arange(5).put(22, -5, mode='raise')) +raises(ValueError, arange(5).put(22, -5, mode='wrongmode')) ___ pypy-commit mailing list pypy-commit@python.org
[pypy-commit] pypy ndarray-ptp: refactored put and added more tests.
Author: Andrews Medina andrewsmed...@gmail.com Branch: ndarray-ptp Changeset: r65139:935fc2578913 Date: 2013-06-28 00:54 -0300 http://bitbucket.org/pypy/pypy/changeset/935fc2578913/ Log:refactored put and added more tests. diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -197,23 +197,35 @@ def put(space, w_arr, w_indices, w_values, mode='raise'): from pypy.module.micronumpy import constants from pypy.module.micronumpy.support import int_w + arr = convert_to_array(space, w_arr) + if mode not in constants.MODES: raise OperationError(space.w_ValueError, space.wrap(mode %s not known % (mode,))) -indices = convert_to_array(space, w_indices) -values = convert_to_array(space, w_values) -if not indices: +if not w_indices: raise OperationError(space.w_ValueError, space.wrap(indice list cannot be empty)) -if not values: +if not w_values: raise OperationError(space.w_ValueError, space.wrap(value list cannot be empty)) + dtype = arr.get_dtype() -val_iter = values.create_iter() -ind_iter = indices.create_iter() -while not ind_iter.done(): -index = int_w(space, ind_iter.getitem()) + +if space.isinstance_w(w_indices, space.w_list): +indices = space.listview(w_indices) +else: +indices = [w_indices] + +if space.isinstance_w(w_values, space.w_list): +values = space.listview(w_values) +else: +values = [w_values] + +v_idx = 0 +for idx in indices: +index = int_w(space, idx) + if index 0 or index = arr.get_size(): if constants.MODES[mode] == constants.MODE_RAISE: raise OperationError(space.w_ValueError, space.wrap( @@ -226,9 +238,13 @@ index = 0 else: index = arr.get_size() - 1 -arr.setitem(space, [index], val_iter.getitem().convert_to(dtype)) -ind_iter.next() -val_iter.next() + +value = values[v_idx] + +if v_idx + 1 len(values): +v_idx += 1 + +arr.setitem(space, [index], dtype.coerce(space, value)) def diagonal(space, arr, offset, axis1, axis2): diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -136,8 +136,14 @@ def test_put_basic(self): from numpypy import arange, array a = arange(5) -a.put([0,2], [-44, -55]) +a.put([0, 2], [-44, -55]) assert (a == array([-44, 1, -55, 3, 4])).all() +a = arange(5) +a.put([3, 4], 9) +assert (a == array([0, 1, 2, 9, 9])).all() +a = arange(5) +a.put(1, [7, 8]) +assert (a == array([0, 7, 2, 3, 4])).all() def test_put_modes(self): from numpypy import array, arange ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Merged in andrewsmedina/numpypy/ndarray-ptp (pull request #157)
Author: Romain Guillebert romain...@gmail.com Branch: Changeset: r65140:1968b8b5d429 Date: 2013-07-01 15:39 +0200 http://bitbucket.org/pypy/pypy/changeset/1968b8b5d429/ Log:Merged in andrewsmedina/numpypy/ndarray-ptp (pull request #157) implemented ndarray put diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -184,6 +184,7 @@ appleveldefs = {} interpleveldefs = { 'choose': 'interp_arrayops.choose', +'put': 'interp_arrayops.put', 'repeat': 'interp_arrayops.repeat', } submodules = { diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -192,6 +192,61 @@ loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) return out + +@unwrap_spec(mode=str) +def put(space, w_arr, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w + +arr = convert_to_array(space, w_arr) + +if mode not in constants.MODES: +raise OperationError(space.w_ValueError, + space.wrap(mode %s not known % (mode,))) +if not w_indices: +raise OperationError(space.w_ValueError, + space.wrap(indice list cannot be empty)) +if not w_values: +raise OperationError(space.w_ValueError, + space.wrap(value list cannot be empty)) + +dtype = arr.get_dtype() + +if space.isinstance_w(w_indices, space.w_list): +indices = space.listview(w_indices) +else: +indices = [w_indices] + +if space.isinstance_w(w_values, space.w_list): +values = space.listview(w_values) +else: +values = [w_values] + +v_idx = 0 +for idx in indices: +index = int_w(space, idx) + +if index 0 or index = arr.get_size(): +if constants.MODES[mode] == constants.MODE_RAISE: +raise OperationError(space.w_ValueError, space.wrap( +invalid entry in choice array)) +elif constants.MODES[mode] == constants.MODE_WRAP: +index = index % arr.get_size() +else: +assert constants.MODES[mode] == constants.MODE_CLIP +if index 0: +index = 0 +else: +index = arr.get_size() - 1 + +value = values[v_idx] + +if v_idx + 1 len(values): +v_idx += 1 + +arr.setitem(space, [index], dtype.coerce(space, value)) + + def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) 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 @@ -550,9 +550,10 @@ raise OperationError(space.w_NotImplementedError, space.wrap( ptp (peak to peak) not implemented yet)) -def descr_put(self, space, w_indices, w_values, w_mode='raise'): -raise OperationError(space.w_NotImplementedError, space.wrap( -put not implemented yet)) +@unwrap_spec(mode=str) +def descr_put(self, space, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy.interp_arrayops import put +put(space, self, w_indices, w_values, mode) def descr_resize(self, space, w_new_shape, w_refcheck=True): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -989,6 +990,7 @@ prod = interp2app(W_NDimArray.descr_prod), max = interp2app(W_NDimArray.descr_max), min = interp2app(W_NDimArray.descr_min), +put = interp2app(W_NDimArray.descr_put), argmax = interp2app(W_NDimArray.descr_argmax), argmin = interp2app(W_NDimArray.descr_argmin), all = interp2app(W_NDimArray.descr_all), diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -132,3 +132,26 @@ x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) assert r.dtype == 'i2' + +def test_put_basic(self): +from numpypy import arange, array +a = arange(5) +a.put([0, 2], [-44, -55]) +assert (a == array([-44, 1, -55, 3, 4])).all() +a = arange(5) +a.put([3, 4], 9) +assert (a == array([0, 1, 2, 9, 9])).all() +a = arange(5) +a.put(1, [7, 8]) +assert (a == array([0, 7, 2, 3, 4])).all() + +def test_put_modes(self): +from numpypy import array, arange +a = arange(5) +a.put(22, -5, mode='clip') +
[pypy-commit] stmgc default: stm_enter_callback_call(), for possibly-recursive invocations
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r336:637f6c9d19f7 Date: 2013-07-01 16:17 +0200 http://bitbucket.org/pypy/stmgc/changeset/637f6c9d19f7/ Log:stm_enter_callback_call(), for possibly-recursive invocations diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1538,15 +1538,14 @@ __thread gcptr stm_thread_local_obj; -int DescriptorInit(void) +void DescriptorInit(void) { if (GCFLAG_PREBUILT != PREBUILT_FLAGS) { stm_fatalerror(fix PREBUILT_FLAGS in stmgc.h by giving it the same value as GCFLAG_PREBUILT!\n); } - - if (thread_descriptor == NULL) + else { revision_t i; struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor)); @@ -1594,16 +1593,14 @@ d-tx_next = stm_tx_head; if (d-tx_next != NULL) d-tx_next-tx_prev = d; stm_tx_head = d; + assert(thread_descriptor == NULL); thread_descriptor = d; dprintf(([%lx] pthread %lx starting\n, (long)d-public_descriptor_index, (long)pthread_self())); stmgcpage_init_tls(); - return 1; } - else -return 0; } void DescriptorDone(void) diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -193,7 +193,7 @@ _Bool stm_has_got_any_lock(struct tx_descriptor *); struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *); -int DescriptorInit(void); +void DescriptorInit(void); void DescriptorDone(void); #endif /* _ET_H */ diff --git a/c4/stmgc.h b/c4/stmgc.h --- a/c4/stmgc.h +++ b/c4/stmgc.h @@ -48,6 +48,12 @@ void stm_initialize(void); void stm_finalize(void); +/* alternate initializers/deinitializers, to use for places that may or + may not be recursive, like callbacks from C code. The return value + of the first one must be passed as argument to the second. */ +int stm_enter_callback_call(void); +void stm_leave_callback_call(int); + /* read/write barriers (the most general versions only for now) */ #if 0 // (optimized version below) gcptr stm_read_barrier(gcptr); diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -77,29 +77,46 @@ d-max_aborts = max_aborts; } +int stm_enter_callback_call(void) +{ +int token = (thread_descriptor == NULL); +if (token == 1) { +stmgcpage_acquire_global_lock(); +DescriptorInit(); +stmgc_init_nursery(); +init_shadowstack(); +stmgcpage_release_global_lock(); +} +BeginInevitableTransaction(); +return token; +} + +void stm_leave_callback_call(int token) +{ +if (token == 1) +stmgc_minor_collect(); /* force everything out of the nursery */ + +CommitTransaction(); + +if (token == 1) { +stmgcpage_acquire_global_lock(); +done_shadowstack(); +stmgc_done_nursery(); +DescriptorDone(); +stmgcpage_release_global_lock(); +} +} + void stm_initialize(void) { -stmgcpage_acquire_global_lock(); -int r = DescriptorInit(); +int r = stm_enter_callback_call(); if (r != 1) -stm_fatalerror(stm_initialize: DescriptorInit failure\n); -stmgc_init_nursery(); -init_shadowstack(); -//stmgcpage_init_tls(); -stmgcpage_release_global_lock(); -BeginInevitableTransaction(); +stm_fatalerror(stm_initialize: already initialized\n); } void stm_finalize(void) { -stmgc_minor_collect(); /* force everything out of the nursery */ -CommitTransaction(); -stmgcpage_acquire_global_lock(); -//stmgcpage_done_tls(); -done_shadowstack(); -stmgc_done_nursery(); -DescriptorDone(); -stmgcpage_release_global_lock(); +stm_leave_callback_call(1); } // diff --git a/c4/test/support.py b/c4/test/support.py --- a/c4/test/support.py +++ b/c4/test/support.py @@ -63,6 +63,8 @@ void stm_set_transaction_length(long length_max); _Bool stm_should_break_transaction(void); long stm_atomic(long delta); +int stm_enter_callback_call(void); +void stm_leave_callback_call(int); /* extra non-public code */ void printfcolor(char *msg); diff --git a/c4/test/test_et.py b/c4/test/test_et.py --- a/c4/test/test_et.py +++ b/c4/test/test_et.py @@ -630,7 +630,15 @@ assert lib.stm_hash(p) != lib.stm_id(p) run_parallel(f1, f2) - - - - +def test_enter_callback_call(): +lib.stm_commit_transaction() +x = lib.stm_enter_callback_call() +assert x == 0 +lib.stm_leave_callback_call(x) +lib.stm_begin_inevitable_transaction() +# +lib.stm_finalize() +x = lib.stm_enter_callback_call() +assert x == 1 +lib.stm_leave_callback_call(x) +lib.stm_initialize_tests(0) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: add -fPIC flag
Author: David Schneider david.schnei...@picle.org Branch: Changeset: r65141:2c5be52130b3 Date: 2013-07-01 17:17 +0200 http://bitbucket.org/pypy/pypy/changeset/2c5be52130b3/ Log:add -fPIC flag diff --git a/rpython/translator/platform/arm.py b/rpython/translator/platform/arm.py --- a/rpython/translator/platform/arm.py +++ b/rpython/translator/platform/arm.py @@ -17,6 +17,7 @@ class ARM(Linux): name = arm +shared_only = ('-fPIC',) available_librarydirs = [SB2 + '/lib/arm-linux-gnueabi/', SB2 + '/lib/arm-linux-gnueabihf/', ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c4: Call invoke_around_extcall() automatically with stm.
Author: Armin Rigo ar...@tunes.org Branch: stmgc-c4 Changeset: r65143:e68bd4bac940 Date: 2013-07-01 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/e68bd4bac940/ Log:Call invoke_around_extcall() automatically with stm. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -56,8 +56,9 @@ leave_callback_call._dont_reach_me_in_del_ = True leave_callback_call._transaction_break_ = True -def invoke_around_extcall(): -Initialize the STM system. Must be called once from the start-up. +def register_invoke_around_extcall(): +Initialize the STM system. +Called automatically by rthread.start_new_thread(). from rpython.rlib.objectmodel import invoke_around_extcall invoke_around_extcall(before_external_call, after_external_call, enter_callback_call, leave_callback_call) diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -97,6 +97,9 @@ @specialize.arg(0) def ll_start_new_thread(func): +if rgc.stm_is_enabled: +from rpython.rlib.rstm import register_invoke_around_extcall +register_invoke_around_extcall() ident = c_thread_start(func) if ident == -1: raise error(can't start new thread) diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -331,13 +331,8 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator entrypoint = self.entrypoint -stm_nogc = (self.config.translation.stm and -self.config.translation.gc == none) # def entrypoint_wrapper(argc, argv): -if stm_nogc: -from rpython.translator.stm.funcgen import _stm_nogc_init_function -_stm_nogc_init_function() list = [] * argc i = 0 while i argc: diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -66,7 +66,6 @@ x.value = 0 glob.seen = x def entry_point(argv): -rstm.invoke_around_extcall() glob.seen = None rthread.start_new_thread(threadfn, ()) while glob.seen is None: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c4: Fix start_new_thread with stm.
Author: Armin Rigo ar...@tunes.org Branch: stmgc-c4 Changeset: r65142:f0f5f39180fd Date: 2013-07-01 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/f0f5f39180fd/ Log:Fix start_new_thread with stm. diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py --- a/rpython/memory/gc/stmgc.py +++ b/rpython/memory/gc/stmgc.py @@ -53,9 +53,10 @@ needs_finalizer=False, is_finalizer_light=False, contains_weakptr=False): -ll_assert(not needs_finalizer, 'XXX') -ll_assert(not is_finalizer_light, 'XXX') -ll_assert(not contains_weakptr, 'XXX') +# XXX finalizers are ignored for now +#ll_assert(not needs_finalizer, 'XXX needs_finalizer') +#ll_assert(not is_finalizer_light, 'XXX is_finalizer_light') +ll_assert(not contains_weakptr, 'XXX contains_weakptr') # XXX call optimized versions, e.g. if size GC_NURSERY_SECTION return llop.stm_allocate(llmemory.GCREF, size, typeid16) diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py --- a/rpython/memory/gctransform/stmframework.py +++ b/rpython/memory/gctransform/stmframework.py @@ -50,12 +50,7 @@ class StmRootWalker(BaseRootWalker): def need_thread_support(self, gctransformer, getfn): -def thread_start(): -llop.stm_initialize(lltype.Void) -def thread_die(): -llop.stm_finalize(lltype.Void) -self.thread_start_ptr = getfn(thread_start, [], annmodel.s_None) -self.thread_die_ptr = getfn(thread_die, [], annmodel.s_None) +pass def walk_stack_roots(self, collect_stack_root): raise NotImplementedError diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -47,17 +47,21 @@ after_external_call._transaction_break_ = True def enter_callback_call(): -# XXX assumes that we're not called in a fresh new thread -llop.stm_begin_inevitable_transaction(lltype.Void) -return 0 +return llop.stm_enter_callback_call(lltype.Signed) enter_callback_call._dont_reach_me_in_del_ = True enter_callback_call._transaction_break_ = True -def leave_callback_call(ignored): -llop.stm_commit_transaction(lltype.Void) +def leave_callback_call(token): +llop.stm_leave_callback_call(lltype.Void, token) leave_callback_call._dont_reach_me_in_del_ = True leave_callback_call._transaction_break_ = True +def invoke_around_extcall(): +Initialize the STM system. Must be called once from the start-up. +from rpython.rlib.objectmodel import invoke_around_extcall +invoke_around_extcall(before_external_call, after_external_call, + enter_callback_call, leave_callback_call) + # def make_perform_transaction(func, CONTAINERP): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -441,6 +441,8 @@ 'stm_change_atomic': LLOp(), 'stm_get_atomic': LLOp(sideeffects=False), 'stm_perform_transaction':LLOp(), +'stm_enter_callback_call':LLOp(), +'stm_leave_callback_call':LLOp(), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(), diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -604,6 +604,8 @@ OP_STM_THREADLOCAL_GET = _OP_STM OP_STM_THREADLOCAL_SET = _OP_STM OP_STM_PERFORM_TRANSACTION = _OP_STM +OP_STM_ENTER_CALLBACK_CALL = _OP_STM +OP_STM_LEAVE_CALLBACK_CALL = _OP_STM def OP_PTR_NONZERO(self, op): diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py --- a/rpython/translator/stm/funcgen.py +++ b/rpython/translator/stm/funcgen.py @@ -151,6 +151,14 @@ arg1 = funcgen.expr(op.args[1]) return 'stm_perform_transaction((gcptr)%s, %s);' % (arg0, arg1) +def stm_enter_callback_call(funcgen, op): +result = funcgen.expr(op.result) +return '%s = stm_enter_callback_call();' % (result,) + +def stm_leave_callback_call(funcgen, op): +arg0 = funcgen.expr(op.args[0]) +return 'stm_leave_callback_call(%s);' % (arg0,) + def op_stm(funcgen, op): func = globals()[op.opname] diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1539,15 +1539,14 @@ __thread gcptr stm_thread_local_obj; -int DescriptorInit(void) +void DescriptorInit(void) { if (GCFLAG_PREBUILT != PREBUILT_FLAGS) { stm_fatalerror(fix PREBUILT_FLAGS in stmgc.h by giving it the same value as
[pypy-commit] pypy inline-identityhash: A branch to experiment with inlining identityhash
Author: Maciej Fijalkowski fij...@gmail.com Branch: inline-identityhash Changeset: r65144:bbf95dc4677f Date: 2013-07-01 17:34 +0200 http://bitbucket.org/pypy/pypy/changeset/bbf95dc4677f/ Log:A branch to experiment with inlining identityhash diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -57,8 +57,8 @@ from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask, r_uint from rpython.rlib.rarithmetic import LONG_BIT_SHIFT from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop -from rpython.rlib.objectmodel import we_are_translated -from rpython.tool.sourcetools import func_with_new_name +from rpython.rlib.objectmodel import specialize + # # Handles the objects in 2 generations: @@ -1824,6 +1824,48 @@ # -- # id() and identityhash() support +def _allocate_shadow(self, obj): +size_gc_header = self.gcheaderbuilder.size_gc_header +size = self.get_size(obj) +shadowhdr = self._malloc_out_of_nursery(size_gc_header + +size) +# Initialize the shadow enough to be considered a +# valid gc object. If the original object stays +# alive at the next minor collection, it will anyway +# be copied over the shadow and overwrite the +# following fields. But if the object dies, then +# the shadow will stay around and only be freed at +# the next major collection, at which point we want +# it to look valid (but ready to be freed). +shadow = shadowhdr + size_gc_header +self.header(shadow).tid = self.header(obj).tid +typeid = self.get_type_id(obj) +if self.is_varsize(typeid): +lenofs = self.varsize_offset_to_length(typeid) +(shadow + lenofs).signed[0] = (obj + lenofs).signed[0] +# +self.header(obj).tid |= GCFLAG_HAS_SHADOW +self.nursery_objects_shadows.setitem(obj, shadow) +return shadow + +def _find_shadow(self, obj): +# +# The object is not a tagged pointer, and it is still in the +# nursery. Find or allocate a shadow object, which is +# where the object will be moved by the next minor +# collection +if self.header(obj).tid GCFLAG_HAS_SHADOW: +shadow = self.nursery_objects_shadows.get(obj) +ll_assert(shadow != NULL, + GCFLAG_HAS_SHADOW but no shadow found) +else: +shadow = self._allocate_shadow(obj) +# +# The answer is the address of the shadow. +return shadow +_find_shadow._dont_inline_ = True + +@specialize.arg(2) def id_or_identityhash(self, gcobj, is_hash): Implement the common logic of id() and identityhash() of an object, given as a GCREF. @@ -1832,41 +1874,7 @@ # if self.is_valid_gc_object(obj): if self.is_in_nursery(obj): -# -# The object is not a tagged pointer, and it is still in the -# nursery. Find or allocate a shadow object, which is -# where the object will be moved by the next minor -# collection -if self.header(obj).tid GCFLAG_HAS_SHADOW: -shadow = self.nursery_objects_shadows.get(obj) -ll_assert(shadow != NULL, - GCFLAG_HAS_SHADOW but no shadow found) -else: -size_gc_header = self.gcheaderbuilder.size_gc_header -size = self.get_size(obj) -shadowhdr = self._malloc_out_of_nursery(size_gc_header + -size) -# Initialize the shadow enough to be considered a -# valid gc object. If the original object stays -# alive at the next minor collection, it will anyway -# be copied over the shadow and overwrite the -# following fields. But if the object dies, then -# the shadow will stay around and only be freed at -# the next major collection, at which point we want -# it to look valid (but ready to be freed). -shadow = shadowhdr + size_gc_header -self.header(shadow).tid = self.header(obj).tid -typeid = self.get_type_id(obj) -if self.is_varsize(typeid): -lenofs = self.varsize_offset_to_length(typeid) -(shadow + lenofs).signed[0] = (obj + lenofs).signed[0] -# -self.header(obj).tid |= GCFLAG_HAS_SHADOW -self.nursery_objects_shadows.setitem(obj, shadow) -# -# The answer
[pypy-commit] pypy default: Fix link in documentation
Author: Markus Unterwaditzer mar...@unterwaditzer.net Branch: Changeset: r65145:ccc1d50f9af9 Date: 2013-07-01 14:11 +0200 http://bitbucket.org/pypy/pypy/changeset/ccc1d50f9af9/ Log:Fix link in documentation diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst --- a/pypy/doc/how-to-contribute.rst +++ b/pypy/doc/how-to-contribute.rst @@ -77,3 +77,4 @@ entry point. .. _`introduction to RPython`: getting-started-dev.html +.. _`pytest`: http://pytest.org/ ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Merged in untitaker/pypy (pull request #158)
Author: arigo armin.r...@gmail.com Branch: Changeset: r65146:4023fff525c0 Date: 2013-07-01 17:41 +0200 http://bitbucket.org/pypy/pypy/changeset/4023fff525c0/ Log:Merged in untitaker/pypy (pull request #158) Fix link in documentation diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst --- a/pypy/doc/how-to-contribute.rst +++ b/pypy/doc/how-to-contribute.rst @@ -77,3 +77,4 @@ entry point. .. _`introduction to RPython`: getting-started-dev.html +.. _`pytest`: http://pytest.org/ ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy inline-identityhash: always inline that guy
Author: Maciej Fijalkowski fij...@gmail.com Branch: inline-identityhash Changeset: r65147:e5c447a98e83 Date: 2013-07-01 19:03 +0200 http://bitbucket.org/pypy/pypy/changeset/e5c447a98e83/ Log:always inline that guy diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -1892,6 +1892,7 @@ if is_hash: i = mangle_hash(i) return i +id_or_identityhash._always_inline_ = True def id(self, gcobj): return self.id_or_identityhash(gcobj, False) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65150:ecacece76689 Date: 2013-07-01 19:53 +0200 http://bitbucket.org/pypy/pypy/changeset/ecacece76689/ Log:merge diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst --- a/pypy/doc/how-to-contribute.rst +++ b/pypy/doc/how-to-contribute.rst @@ -77,3 +77,4 @@ entry point. .. _`introduction to RPython`: getting-started-dev.html +.. _`pytest`: http://pytest.org/ diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -184,6 +184,7 @@ appleveldefs = {} interpleveldefs = { 'choose': 'interp_arrayops.choose', +'put': 'interp_arrayops.put', 'repeat': 'interp_arrayops.repeat', } submodules = { diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -192,6 +192,61 @@ loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) return out + +@unwrap_spec(mode=str) +def put(space, w_arr, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w + +arr = convert_to_array(space, w_arr) + +if mode not in constants.MODES: +raise OperationError(space.w_ValueError, + space.wrap(mode %s not known % (mode,))) +if not w_indices: +raise OperationError(space.w_ValueError, + space.wrap(indice list cannot be empty)) +if not w_values: +raise OperationError(space.w_ValueError, + space.wrap(value list cannot be empty)) + +dtype = arr.get_dtype() + +if space.isinstance_w(w_indices, space.w_list): +indices = space.listview(w_indices) +else: +indices = [w_indices] + +if space.isinstance_w(w_values, space.w_list): +values = space.listview(w_values) +else: +values = [w_values] + +v_idx = 0 +for idx in indices: +index = int_w(space, idx) + +if index 0 or index = arr.get_size(): +if constants.MODES[mode] == constants.MODE_RAISE: +raise OperationError(space.w_ValueError, space.wrap( +invalid entry in choice array)) +elif constants.MODES[mode] == constants.MODE_WRAP: +index = index % arr.get_size() +else: +assert constants.MODES[mode] == constants.MODE_CLIP +if index 0: +index = 0 +else: +index = arr.get_size() - 1 + +value = values[v_idx] + +if v_idx + 1 len(values): +v_idx += 1 + +arr.setitem(space, [index], dtype.coerce(space, value)) + + def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) 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 @@ -550,9 +550,10 @@ raise OperationError(space.w_NotImplementedError, space.wrap( ptp (peak to peak) not implemented yet)) -def descr_put(self, space, w_indices, w_values, w_mode='raise'): -raise OperationError(space.w_NotImplementedError, space.wrap( -put not implemented yet)) +@unwrap_spec(mode=str) +def descr_put(self, space, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy.interp_arrayops import put +put(space, self, w_indices, w_values, mode) def descr_resize(self, space, w_new_shape, w_refcheck=True): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -989,6 +990,7 @@ prod = interp2app(W_NDimArray.descr_prod), max = interp2app(W_NDimArray.descr_max), min = interp2app(W_NDimArray.descr_min), +put = interp2app(W_NDimArray.descr_put), argmax = interp2app(W_NDimArray.descr_argmax), argmin = interp2app(W_NDimArray.descr_argmin), all = interp2app(W_NDimArray.descr_all), diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -132,3 +132,26 @@ x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) assert r.dtype == 'i2' + +def test_put_basic(self): +from numpypy import arange, array +a = arange(5) +a.put([0, 2], [-44, -55]) +assert (a == array([-44, 1, -55, 3, 4])).all() +a = arange(5) +a.put([3, 4], 9) +assert (a == array([0, 1, 2, 9, 9])).all() +a = arange(5) +a.put(1, [7, 8]) +
[pypy-commit] pypy inline-identityhash: close to-be-merged branch
Author: Maciej Fijalkowski fij...@gmail.com Branch: inline-identityhash Changeset: r65148:0c75c6e3b735 Date: 2013-07-01 19:47 +0200 http://bitbucket.org/pypy/pypy/changeset/0c75c6e3b735/ Log:close to-be-merged branch ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge inline-identityhash - it gives a measurable speedup (~25%) on
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65149:f75c60186757 Date: 2013-07-01 19:52 +0200 http://bitbucket.org/pypy/pypy/changeset/f75c60186757/ Log:merge inline-identityhash - it gives a measurable speedup (~25%) on microbenchmarks, like set comparison. Seems to have no real downsides diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -57,8 +57,8 @@ from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask, r_uint from rpython.rlib.rarithmetic import LONG_BIT_SHIFT from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop -from rpython.rlib.objectmodel import we_are_translated -from rpython.tool.sourcetools import func_with_new_name +from rpython.rlib.objectmodel import specialize + # # Handles the objects in 2 generations: @@ -1824,6 +1824,48 @@ # -- # id() and identityhash() support +def _allocate_shadow(self, obj): +size_gc_header = self.gcheaderbuilder.size_gc_header +size = self.get_size(obj) +shadowhdr = self._malloc_out_of_nursery(size_gc_header + +size) +# Initialize the shadow enough to be considered a +# valid gc object. If the original object stays +# alive at the next minor collection, it will anyway +# be copied over the shadow and overwrite the +# following fields. But if the object dies, then +# the shadow will stay around and only be freed at +# the next major collection, at which point we want +# it to look valid (but ready to be freed). +shadow = shadowhdr + size_gc_header +self.header(shadow).tid = self.header(obj).tid +typeid = self.get_type_id(obj) +if self.is_varsize(typeid): +lenofs = self.varsize_offset_to_length(typeid) +(shadow + lenofs).signed[0] = (obj + lenofs).signed[0] +# +self.header(obj).tid |= GCFLAG_HAS_SHADOW +self.nursery_objects_shadows.setitem(obj, shadow) +return shadow + +def _find_shadow(self, obj): +# +# The object is not a tagged pointer, and it is still in the +# nursery. Find or allocate a shadow object, which is +# where the object will be moved by the next minor +# collection +if self.header(obj).tid GCFLAG_HAS_SHADOW: +shadow = self.nursery_objects_shadows.get(obj) +ll_assert(shadow != NULL, + GCFLAG_HAS_SHADOW but no shadow found) +else: +shadow = self._allocate_shadow(obj) +# +# The answer is the address of the shadow. +return shadow +_find_shadow._dont_inline_ = True + +@specialize.arg(2) def id_or_identityhash(self, gcobj, is_hash): Implement the common logic of id() and identityhash() of an object, given as a GCREF. @@ -1832,41 +1874,7 @@ # if self.is_valid_gc_object(obj): if self.is_in_nursery(obj): -# -# The object is not a tagged pointer, and it is still in the -# nursery. Find or allocate a shadow object, which is -# where the object will be moved by the next minor -# collection -if self.header(obj).tid GCFLAG_HAS_SHADOW: -shadow = self.nursery_objects_shadows.get(obj) -ll_assert(shadow != NULL, - GCFLAG_HAS_SHADOW but no shadow found) -else: -size_gc_header = self.gcheaderbuilder.size_gc_header -size = self.get_size(obj) -shadowhdr = self._malloc_out_of_nursery(size_gc_header + -size) -# Initialize the shadow enough to be considered a -# valid gc object. If the original object stays -# alive at the next minor collection, it will anyway -# be copied over the shadow and overwrite the -# following fields. But if the object dies, then -# the shadow will stay around and only be freed at -# the next major collection, at which point we want -# it to look valid (but ready to be freed). -shadow = shadowhdr + size_gc_header -self.header(shadow).tid = self.header(obj).tid -typeid = self.get_type_id(obj) -if self.is_varsize(typeid): -lenofs = self.varsize_offset_to_length(typeid) -(shadow + lenofs).signed[0] = (obj + lenofs).signed[0] -# -self.header(obj).tid |= GCFLAG_HAS_SHADOW -
[pypy-commit] pypy default: document the branch
Author: Maciej Fijalkowski fij...@gmail.com Branch: Changeset: r65151:a4b1d73be06f Date: 2013-07-01 19:55 +0200 http://bitbucket.org/pypy/pypy/changeset/a4b1d73be06f/ Log:document the branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -67,3 +67,6 @@ .. branch: identity-set Faster sets for objects + +.. branch: inline-identityhash +Inline the fast path of id() and hash() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: 2to3
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r65152:6be53cd7a876 Date: 2013-07-01 11:30 -0700 http://bitbucket.org/pypy/pypy/changeset/6be53cd7a876/ Log:2to3 diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -25,8 +25,7 @@ ('gr_mem', POINTER(c_char_p)), ) -class struct_group: -__metaclass__ = _structseq.structseqtype +class struct_group(metaclass=_structseq.structseqtype): gr_name = _structseq.structseqfield(0) gr_passwd = _structseq.structseqfield(1) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy numpypy-segfault: a test that segfaults
Author: Matti Picus matti.pi...@gmail.com Branch: numpypy-segfault Changeset: r65153:f669a32fe79d Date: 2013-06-30 22:56 +0300 http://bitbucket.org/pypy/pypy/changeset/f669a32fe79d/ Log:a test that segfaults 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 @@ -293,6 +293,17 @@ b = array(a, copy=False, ndmin=4) b[0,0,0,0] = 0 assert a[0, 0] == 0 +a = array([[[]]]) +# Simulate tiling an empty array, really tests repeat, reshape +# b = tile(a, (3, 2, 5)) +reps = (3, 4, 5) +c = array(a, copy=False, subok=True, ndmin=len(reps)) +print '1',c,c.shape +d = c.reshape(3, 4, 0) +print '2',c,c.shape +e = d.repeat(3, 0) +print '3',c,c.shape,e.shape +assert e.shape == (9, 4, 0) def test_type(self): from numpypy import array ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy numpypy-segfault: test, fix creating empty axis iterator
Author: Matti Picus matti.pi...@gmail.com Branch: numpypy-segfault Changeset: r65155:df376dab84d2 Date: 2013-07-02 00:00 +0300 http://bitbucket.org/pypy/pypy/changeset/df376dab84d2/ Log:test, fix creating empty axis iterator diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -285,7 +285,7 @@ self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] self.first_line = True self.indices = [0] * len(shape) -self._done = False +self._done = array.get_size() == 0 self.offset = array.start self.dim = dim self.array = array 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 @@ -298,11 +298,8 @@ # b = tile(a, (3, 2, 5)) reps = (3, 4, 5) c = array(a, copy=False, subok=True, ndmin=len(reps)) -print '1',c,c.shape d = c.reshape(3, 4, 0) -print '2',c,c.shape e = d.repeat(3, 0) -print '3',c,c.shape,e.shape assert e.shape == (9, 4, 0) def test_type(self): @@ -2573,6 +2570,9 @@ a = array(range(100) + range(100) + range(100)) b = a.argsort() assert (b[:3] == [0, 100, 200]).all() +a = array([[[]]]).reshape(3,4,0) +b = a.argsort() +assert b.size == 0 def test_argsort_random(self): from numpypy import array ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: Fix tests: in the py3k branch, we parse unicode strings
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: py3k Changeset: r65156:18f3a937ce30 Date: 2013-07-01 23:38 +0200 http://bitbucket.org/pypy/pypy/changeset/18f3a937ce30/ Log:Fix tests: in the py3k branch, we parse unicode strings and 'L' suffix is not allowed. diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -418,49 +418,49 @@ class TestStringToInt: def test_string_to_int(self): -cases = [('0', 0), - ('1', 1), - ('9', 9), - ('10', 10), - ('09', 9), - ('101', 101),# not octal unless base 0 or 8 - ('5123', 5123), - (' 0', 0), - ('0 ', 0), - (' \t \n 32313 \f \v \r \n\r', 32313), - ('+12', 12), - ('-5', -5), - ('- 5', -5), - ('+ 5', 5), - (' -123456789 ', -123456789), +cases = [(u'0', 0), + (u'1', 1), + (u'9', 9), + (u'10', 10), + (u'09', 9), + (u'101', 101),# not octal unless base 0 or 8 + (u'5123', 5123), + (u' 0', 0), + (u'0 ', 0), + (u' \t \n 32313 \f \v \r \n\r', 32313), + (u'+12', 12), + (u'-5', -5), + (u'- 5', -5), + (u'+ 5', 5), + (u' -123456789 ', -123456789), ] for s, expected in cases: assert string_to_int(s) == expected #assert string_to_bigint(s).tolong() == expected def test_string_to_int_base(self): -cases = [('111', 2, 7), - ('010', 2, 2), - ('102', 3, 11), - ('103', 4, 19), - ('107', 8, 71), - ('109', 10, 109), - ('10A', 11, 131), - ('10a', 11, 131), - ('10f', 16, 271), - ('10F', 16, 271), - ('0x10f', 16, 271), - ('0x10F', 16, 271), - ('10z', 36, 1331), - ('10Z', 36, 1331), - ('12', 0, 12), - ('015', 0, 13), - ('0x10', 0, 16), - ('0XE', 0, 14), - ('0',0, 0), - ('0b11', 2, 3), - ('0B10', 2, 2), - ('0o77', 8, 63), +cases = [(u'111', 2, 7), + (u'010', 2, 2), + (u'102', 3, 11), + (u'103', 4, 19), + (u'107', 8, 71), + (u'109', 10, 109), + (u'10A', 11, 131), + (u'10a', 11, 131), + (u'10f', 16, 271), + (u'10F', 16, 271), + (u'0x10f', 16, 271), + (u'0x10F', 16, 271), + (u'10z', 36, 1331), + (u'10Z', 36, 1331), + (u'12', 0, 12), + (u'015', 0, 13), + (u'0x10', 0, 16), + (u'0XE', 0, 14), + (u'0',0, 0), + (u'0b11', 2, 3), + (u'0B10', 2, 2), + (u'0o77', 8, 63), ] for s, base, expected in cases: assert string_to_int(s, base) == expected @@ -471,21 +471,21 @@ assert string_to_int('-'+s+' ', base) == -expected def test_string_to_int_error(self): -cases = ['0x123',# must use base 0 or 16 - ' 0X12 ', - '0b01', - '0o01', - '', - '++12', - '+-12', - '-+12', - '--12', - '12a6', - '12A6', - 'f', - 'Z', - '.', - '@', +cases = [u'0x123',# must use base 0 or 16 + u' 0X12 ', + u'0b01', + u'0o01', + u'', + u'++12', + u'+-12', + u'-+12', + u'--12', + u'12a6', + u'12A6', + u'f', + u'Z', + u'.', + u'@', ] for s in cases: py.test.raises(ParseStringError, string_to_int, s) @@ -493,39 +493,39 @@ py.test.raises(ParseStringError, string_to_int, s+' ') py.test.raises(ParseStringError, string_to_int, '+'+s) py.test.raises(ParseStringError, string_to_int, '-'+s) -py.test.raises(ParseStringError, string_to_int, '0x', 16) -py.test.raises(ParseStringError, string_to_int, '-0x', 16) +
[pypy-commit] pypy py3k: we don't actually utf8 encode here, so lighten the expectation to a ValueError
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r65157:ce22f20c0ada Date: 2013-07-01 16:18 -0700 http://bitbucket.org/pypy/pypy/changeset/ce22f20c0ada/ Log:we don't actually utf8 encode here, so lighten the expectation to a ValueError 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 @@ -446,7 +446,7 @@ def test_from_string(self): raises(ValueError, float, \0) -raises(UnicodeEncodeError, float, '\uD8F0') +raises(ValueError, float, '\uD8F0') def test_format(self): f = 1.1234e200 ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: merge default
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r65160:98718a061cac Date: 2013-07-01 16:34 -0700 http://bitbucket.org/pypy/pypy/changeset/98718a061cac/ Log:merge default diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -132,7 +132,8 @@ _tls.main = gmain _tls.current = gmain -def _greenlet_start(greenlet, (args, kwds)): +def _greenlet_start(greenlet, args): +args, kwds = args _tls.current = greenlet try: res = greenlet.run(*args, **kwds) diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst --- a/pypy/doc/how-to-contribute.rst +++ b/pypy/doc/how-to-contribute.rst @@ -77,3 +77,4 @@ entry point. .. _`introduction to RPython`: getting-started-dev.html +.. _`pytest`: http://pytest.org/ diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,8 @@ .. branch: ndarray-view Add view to ndarray and zeroD arrays, not on dtype scalars yet +.. branch: identity-set +Faster sets for objects + +.. branch: inline-identityhash +Inline the fast path of id() and hash() diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -184,6 +184,7 @@ appleveldefs = {} interpleveldefs = { 'choose': 'interp_arrayops.choose', +'put': 'interp_arrayops.put', 'repeat': 'interp_arrayops.repeat', } submodules = { diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -13,6 +13,9 @@ def next(self): self.called_once = True +def next_skip_x(self, n): +self.called_once = True + def getitem(self): return self.v.get_scalar_value() diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -192,6 +192,61 @@ loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) return out + +@unwrap_spec(mode=str) +def put(space, w_arr, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w + +arr = convert_to_array(space, w_arr) + +if mode not in constants.MODES: +raise OperationError(space.w_ValueError, + space.wrap(mode %s not known % (mode,))) +if not w_indices: +raise OperationError(space.w_ValueError, + space.wrap(indice list cannot be empty)) +if not w_values: +raise OperationError(space.w_ValueError, + space.wrap(value list cannot be empty)) + +dtype = arr.get_dtype() + +if space.isinstance_w(w_indices, space.w_list): +indices = space.listview(w_indices) +else: +indices = [w_indices] + +if space.isinstance_w(w_values, space.w_list): +values = space.listview(w_values) +else: +values = [w_values] + +v_idx = 0 +for idx in indices: +index = int_w(space, idx) + +if index 0 or index = arr.get_size(): +if constants.MODES[mode] == constants.MODE_RAISE: +raise OperationError(space.w_ValueError, space.wrap( +invalid entry in choice array)) +elif constants.MODES[mode] == constants.MODE_WRAP: +index = index % arr.get_size() +else: +assert constants.MODES[mode] == constants.MODE_CLIP +if index 0: +index = 0 +else: +index = arr.get_size() - 1 + +value = values[v_idx] + +if v_idx + 1 len(values): +v_idx += 1 + +arr.setitem(space, [index], dtype.coerce(space, value)) + + def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) 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 @@ -550,9 +550,10 @@ raise OperationError(space.w_NotImplementedError, space.wrap( ptp (peak to peak) not implemented yet)) -def descr_put(self, space, w_indices, w_values, w_mode='raise'): -raise OperationError(space.w_NotImplementedError, space.wrap( -put not implemented yet)) +@unwrap_spec(mode=str) +def descr_put(self, space, w_indices, w_values, mode='raise'): +from pypy.module.micronumpy.interp_arrayops import put +put(space, self, w_indices, w_values, mode) def descr_resize(self, space,
[pypy-commit] pypy default: py3k compat
Author: Philip Jenvey pjen...@underboss.org Branch: Changeset: r65158:7a85cc22a4c9 Date: 2013-07-01 16:28 -0700 http://bitbucket.org/pypy/pypy/changeset/7a85cc22a4c9/ Log:py3k compat diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -132,7 +132,8 @@ _tls.main = gmain _tls.current = gmain -def _greenlet_start(greenlet, (args, kwds)): +def _greenlet_start(greenlet, args): +args, kwds = args _tls.current = greenlet try: res = greenlet.run(*args, **kwds) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: whitespace
Author: Philip Jenvey pjen...@underboss.org Branch: Changeset: r65159:2ee41b828b47 Date: 2013-07-01 16:32 -0700 http://bitbucket.org/pypy/pypy/changeset/2ee41b828b47/ Log:whitespace diff --git a/pypy/objspace/std/test/test_identityset.py b/pypy/objspace/std/test/test_identityset.py --- a/pypy/objspace/std/test/test_identityset.py +++ b/pypy/objspace/std/test/test_identityset.py @@ -1,23 +1,22 @@ import py +class AppTestIdentitySet(object): -class AppTestIdentitySet(object): - -#needed for compares_by_identity +# needed for compares_by_identity spaceconfig = {objspace.std.withidentitydict: True} - + def setup_class(cls): from pypy.objspace.std import identitydict if cls.runappdirect: py.test.skip(interp2app doesn't work on appdirect) - + def w_uses_strategy(self, s , obj): import __pypy__ return s in __pypy__.internal_repr(obj) - + def test_use_identity_strategy(self): - + class Plain(object): pass @@ -32,113 +31,113 @@ class CustomHash(object): def __hash__(self): return 0 - + s = set() - + assert not self.uses_strategy('IdentitySetStrategy',s) - + s.add(Plain()) - + assert self.uses_strategy('IdentitySetStrategy',s) - + for cls in [CustomEq,CustomCmp,CustomHash]: s = set() s.add(cls()) assert not self.uses_strategy('IdentitySetStrategy',s) - - + + def test_use_identity_strategy_list(self): - + class X(object): pass - + assert self.uses_strategy('IdentitySetStrategy',set([X(),X()])) assert not self.uses_strategy('IdentitySetStrategy',set([X(),])) assert not self.uses_strategy('IdentitySetStrategy',set([X(),u])) assert not self.uses_strategy('IdentitySetStrategy',set([X(),1])) - + def test_identity_strategy_add(self): - + class X(object): pass - + class NotIdent(object): def __eq__(self,other): pass - + s = set([X(),X()]) s.add('foo') assert not self.uses_strategy('IdentitySetStrategy',s) s = set([X(),X()]) s.add(NotIdent()) assert not self.uses_strategy('IdentitySetStrategy',s) - + def test_identity_strategy_sanity(self): - + class X(object): pass - + class Y(object): pass - + a,b,c,d,e,f = X(),Y(),X(),Y(),X(),Y() - + s = set([a,b]).union(set([c])) -assert self.uses_strategy('IdentitySetStrategy',s) +assert self.uses_strategy('IdentitySetStrategy',s) assert set([a,b,c]) == s s = set([a,b,c,d,e,f]) - set([d,e,f]) assert self.uses_strategy('IdentitySetStrategy',s) assert set([a,b,c]) == s - - + + s = set([a]) s.update([b,c]) - + assert s == set([a,b,c]) - - + + def test_identity_strategy_iterators(self): - + class X(object): pass - + s = set([X() for i in range(10)]) counter = 0 for item in s: counter += 1 assert item in s - + assert counter == 10 - - + + def test_identity_strategy_other_cmp(self): - -#test tries to hit positive and negative in + +# test tries to hit positive and negative in # may_contain_equal_elements - + class X(object): pass - -s = set([X() for i in range(10)]) - + +s = set([X() for i in range(10)]) + assert s.intersection(set([1,2,3])) == set() assert s.intersection(set(['a','b','c'])) == set() assert s.intersection(set(['a','b','c'])) == set() assert s.intersection(set([X(),X()])) == set() - + other = set(['a','b','c',s.__iter__().next()]) intersect = s.intersection(other) assert len(intersect) == 1 assert intersect.__iter__().next() in s assert intersect.__iter__().next() in other - + def test_class_monkey_patch(self): - + class X(object): pass - + s = set() - + s.add(X()) assert self.uses_strategy('IdentitySetStrategy',s) X.__eq__ = lambda self,other : None @@ -148,47 +147,47 @@ assert not self.uses_strategy('IdentitySetStrategy',set([X(),])) assert not self.uses_strategy('IdentitySetStrategy',set([X(),u])) assert not self.uses_strategy('IdentitySetStrategy',set([X(),1])) - -# An interesting case, add an instance, mutate the class, + +# An interesting case, add an instance,
[pypy-commit] pypy numpypy-segfault: close to-be-merged branch
Author: Matti Picus matti.pi...@gmail.com Branch: numpypy-segfault Changeset: r65162:a038818305e0 Date: 2013-07-02 07:51 +0300 http://bitbucket.org/pypy/pypy/changeset/a038818305e0/ Log:close to-be-merged branch ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy numpypy-segfault: document branch
Author: Matti Picus matti.pi...@gmail.com Branch: numpypy-segfault Changeset: r65161:5e52e47a4a8d Date: 2013-07-02 07:51 +0300 http://bitbucket.org/pypy/pypy/changeset/5e52e47a4a8d/ Log:document branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,6 @@ .. branch: ndarray-view Add view to ndarray and zeroD arrays, not on dtype scalars yet +.. branch: numpypy-segfault +fix segfault caused by iterating over empty ndarrays + ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge numpypy-segfault fixing segfault while iterating over empty ndarrays
Author: Matti Picus matti.pi...@gmail.com Branch: Changeset: r65163:49b114578eb7 Date: 2013-07-02 07:54 +0300 http://bitbucket.org/pypy/pypy/changeset/49b114578eb7/ Log:merge numpypy-segfault fixing segfault while iterating over empty ndarrays diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,6 +65,9 @@ .. branch: ndarray-view Add view to ndarray and zeroD arrays, not on dtype scalars yet +.. branch: numpypy-segfault +fix segfault caused by iterating over empty ndarrays + .. branch: identity-set Faster sets for objects diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -65,7 +65,7 @@ [ 3., 4., -1.], [-1., -1., -1.]]) - + NOTE: support for not passing x and y is unsupported if space.is_none(w_y): @@ -122,10 +122,10 @@ for f in dtype.fields: if f not in a_dt.fields or \ dtype.fields[f] != a_dt.fields[f]: -raise OperationError(space.w_TypeError, +raise OperationError(space.w_TypeError, space.wrap(record type mismatch)) elif dtype.is_record_type() or a_dt.is_record_type(): -raise OperationError(space.w_TypeError, +raise OperationError(space.w_TypeError, space.wrap(invalid type promotion)) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -46,6 +46,7 @@ calculate_slice_strides from pypy.module.micronumpy.base import W_NDimArray from pypy.module.micronumpy.arrayimpl import base +from pypy.module.micronumpy.support import product from rpython.rlib import jit # structures to describe slicing @@ -225,7 +226,7 @@ self.shape = shape self.offset = start self.shapelen = len(shape) -self._done = False +self._done = self.shapelen == 0 or product(shape) == 0 self.strides = strides self.backstrides = backstrides self.size = array.size @@ -284,7 +285,7 @@ self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] self.first_line = True self.indices = [0] * len(shape) -self._done = False +self._done = array.get_size() == 0 self.offset = array.start self.dim = dim self.array = array 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 @@ -293,6 +293,14 @@ b = array(a, copy=False, ndmin=4) b[0,0,0,0] = 0 assert a[0, 0] == 0 +a = array([[[]]]) +# Simulate tiling an empty array, really tests repeat, reshape +# b = tile(a, (3, 2, 5)) +reps = (3, 4, 5) +c = array(a, copy=False, subok=True, ndmin=len(reps)) +d = c.reshape(3, 4, 0) +e = d.repeat(3, 0) +assert e.shape == (9, 4, 0) def test_type(self): from numpypy import array @@ -2562,6 +2570,9 @@ a = array(range(100) + range(100) + range(100)) b = a.argsort() assert (b[:3] == [0, 100, 200]).all() +a = array([[[]]]).reshape(3,4,0) +b = a.argsort() +assert b.size == 0 def test_argsort_random(self): from numpypy import array ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: add build and release versions of demo_random to tests
Author: Remi Meier meier...@student.ethz.ch Branch: Changeset: r337:d197afc97b0e Date: 2013-07-02 07:53 +0200 http://bitbucket.org/pypy/stmgc/changeset/d197afc97b0e/ Log:add build and release versions of demo_random to tests diff --git a/c4/test/test_zdemo_random.py b/c4/test/test_zdemo_random.py --- a/c4/test/test_zdemo_random.py +++ b/c4/test/test_zdemo_random.py @@ -2,7 +2,7 @@ import os import subprocess -def test_and_run(): +def test_and_run_debug(): path = os.path.dirname(__file__) path = os.path.dirname(path) res = subprocess.call([make, debug-demo_random], cwd=path) @@ -10,4 +10,19 @@ res = subprocess.call([./debug-demo_random], cwd=path) assert not res - +def test_and_run_build(): +path = os.path.dirname(__file__) +path = os.path.dirname(path) +res = subprocess.call([make, build-demo_random], cwd=path) +assert not res +res = subprocess.call([./build-demo_random], cwd=path) +assert not res + +def test_and_run_release(): +path = os.path.dirname(__file__) +path = os.path.dirname(path) +res = subprocess.call([make, release-demo_random], cwd=path) +assert not res +res = subprocess.call([./release-demo_random], cwd=path) +assert not res + ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit