[pypy-commit] pypy stmgc-c7: Light finalizers: still a problem if they call some function like close(),

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: stmgc-c7
Changeset: r74011:6355617bf9a2
Date: 2014-10-18 09:14 +0200
http://bitbucket.org/pypy/pypy/changeset/6355617bf9a2/

Log:Light finalizers: still a problem if they call some function like
close(), because that triggers stm_become_inevitable(), which can
pause and run gc collections --- not supported in light finalizers.

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
@@ -78,7 +78,8 @@
 if contains_weakptr:# check constant-folded
 return llop.stm_allocate_weakref(llmemory.GCREF, size, typeid16)
 if needs_finalizer:
-#is_finalizer_light  XXX ignored now
+#if is_finalizer_light:   XXX implement me
+#   return llop.stm_allocate_f_light(llmemory.GCREF, size, 
typeid16)
 return llop.stm_allocate_finalizer(llmemory.GCREF, size, typeid16)
 return llop.stm_allocate_tid(llmemory.GCREF, size, typeid16)
 
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
@@ -418,6 +418,7 @@
 'stm_allocate_tid':   LLOp(sideeffects=False, canmallocgc=True),
 'stm_allocate_weakref':   LLOp(sideeffects=False, canmallocgc=True),
 'stm_allocate_finalizer': LLOp(sideeffects=False, canmallocgc=True),
+'stm_allocate_f_light':   LLOp(sideeffects=False, canmallocgc=True),
 'stm_get_from_obj':   LLOp(sideeffects=False),
 'stm_get_from_obj_const': LLOp(canfold=True),
 'stm_set_into_obj':   LLOp(),
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
@@ -98,6 +98,16 @@
 result, arg_size) +
 '((rpyobj_t *)%s)->tid = %s;' % (result, arg_type_id))
 
+def stm_allocate_f_light(funcgen, op):
+arg_size= funcgen.expr(op.args[0])
+arg_type_id = funcgen.expr(op.args[1])
+result  = funcgen.expr(op.result)
+# XXX NULL returns?
+return ('%s = (rpygcchar_t *)stm_allocate(%s); ' % (
+result, arg_size) +
+'((rpyobj_t *)%s)->tid = %s;\n' % (result, arg_type_id) +
+'stm_enable_light_finalizer(%s);' % (result,))
+
 def stm_get_from_obj(funcgen, op):
 assert op.args[0].concretetype == llmemory.GCREF
 arg_obj = funcgen.expr(op.args[0])
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
@@ -535,6 +535,7 @@
 assert 'destructors called: 1\n' in data
 
 def test_light_finalizer(self):
+py.test.skip("XXX implement me")
 class X:
 @rgc.must_be_light_finalizer
 def __del__(self):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] extradoc extradoc: (fijal, arigo) start working on slides

2014-10-18 Thread fijal
Author: Maciej Fijalkowski 
Branch: extradoc
Changeset: r5441:e25d84db6be0
Date: 2014-10-18 15:47 +0200
http://bitbucket.org/pypy/extradoc/changeset/e25d84db6be0/

Log:(fijal, arigo) start working on slides

diff --git a/talk/pyconpl-2014/benchmarks/abstract.rst 
b/talk/pyconpl-2014/benchmarks/abstract.rst
new file mode 100644
--- /dev/null
+++ b/talk/pyconpl-2014/benchmarks/abstract.rst
@@ -0,0 +1,7 @@
+How to benchmark code
+-
+
+In this talk, we would like to present basics of how the Python virtual 
machines
+like CPython or PyPy work and how to use that knowledge to write meaningful
+benchmarks for your programs. We'll show what's wrong with microbenchmarks
+and how to improve the situation.
diff --git a/talk/pyconpl-2014/benchmarks/f1.py 
b/talk/pyconpl-2014/benchmarks/f1.py
new file mode 100644
--- /dev/null
+++ b/talk/pyconpl-2014/benchmarks/f1.py
@@ -0,0 +1,8 @@
+
+def f():
+i = 0
+while i < 1:
+i += 1
+return i
+
+f()
diff --git a/talk/pyconpl-2014/benchmarks/f2.py 
b/talk/pyconpl-2014/benchmarks/f2.py
new file mode 100644
--- /dev/null
+++ b/talk/pyconpl-2014/benchmarks/f2.py
@@ -0,0 +1,10 @@
+
+def f():
+i = 0
+s = 0
+while i < 1:
+s += len(str(i))
+i += 1
+return s
+
+print f()
diff --git a/talk/pyconpl-2014/benchmarks/fib.py 
b/talk/pyconpl-2014/benchmarks/fib.py
new file mode 100644
--- /dev/null
+++ b/talk/pyconpl-2014/benchmarks/fib.py
@@ -0,0 +1,27 @@
+
+import time
+import numpy
+from matplotlib import pylab
+
+def fib(n):
+if n == 0 or n == 1:
+return 1
+return fib(n - 1) + fib(n - 2)
+
+def f():
+for i in range(1):
+"".join(list(str(i)))
+
+times = []
+for i in xrange(1000):
+t0 = time.time()
+#f()
+fib(17)
+times.append(time.time() - t0)
+
+hist, bins = numpy.histogram(times, 20)
+#pylab.plot(bins[:-1], hist)
+pylab.ylim(ymin=0, ymax=max(times) * 1.2)
+pylab.plot(times)
+#pylab.hist(hist, bins, histtype='bar')
+pylab.show()
diff --git a/talk/pyconpl-2014/benchmarks/talk.rst 
b/talk/pyconpl-2014/benchmarks/talk.rst
new file mode 100644
--- /dev/null
+++ b/talk/pyconpl-2014/benchmarks/talk.rst
@@ -0,0 +1,78 @@
+-
+How to benchmark code
+-
+
+Who are we?
+
+
+xxx
+
+What is this talk is about?
+---
+
+* basics how CPython and PyPy run programs
+
+* a bit of theory about measuring performance
+
+* microbenchmarks
+
+* complicated picture of "real world"
+
+CPython
+---
+
+* a "simple" virtual machine
+
+* compiles python code to bytecode
+
+* runs the bytecode
+
+* usually invokes tons of runtime functions written in C
+
+CPython (demo)
+--
+
+PyPy
+
+
+* not so simple virtual machine
+
+* all of the above
+
+* ... and then if the loop/function gets called often enough
+  it's compiled down to an optimized assembler by the JIT
+
+PyPy (demo)
+---
+
+Measurments 101
+---
+
+* run your benchmark multiple times
+
+* the distribution should be gaussian
+
+* take the average and the variation
+
+* if the variation is too large, increase the number of iterations
+
+Let's do it (demo)
+--
+
+Problems
+
+
+* the whole previous slide is a bunch of nonsense
+
+* ...
+
+"Solution"
+--
+
+* you try your best and do the average anyway
+
+* presumably cutting off the warmup time
+
+|pause|
+
+* not ideal at all
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] extradoc extradoc: merge

2014-10-18 Thread fijal
Author: Maciej Fijalkowski 
Branch: extradoc
Changeset: r5442:bb1fcacdc6cb
Date: 2014-10-18 15:48 +0200
http://bitbucket.org/pypy/extradoc/changeset/bb1fcacdc6cb/

Log:merge

diff --git a/talk/pyconpl-2014/talk.pdf b/talk/pyconpl-2014/talk.pdf
new file mode 100644
index 
..96cfd649da81c326dec0dbe7d92087b9864229d7
GIT binary patch

[cut]

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


[pypy-commit] stmgc hashtable: A branch to add "hashtable" support in stmgc

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: hashtable
Changeset: r1478:27943c928c3c
Date: 2014-10-18 16:54 +0200
http://bitbucket.org/pypy/stmgc/changeset/27943c928c3c/

Log:A branch to add "hashtable" support in stmgc

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


[pypy-commit] stmgc hashtable: Import initial untested logic

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: hashtable
Changeset: r1479:04bcef9511f9
Date: 2014-10-18 17:09 +0200
http://bitbucket.org/pypy/stmgc/changeset/04bcef9511f9/

Log:Import initial untested logic

diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
new file mode 100644
--- /dev/null
+++ b/c7/stm/hashtable.c
@@ -0,0 +1,276 @@
+#include "stmgc.h"
+
+/*
+Design of stmgc's "hashtable" objects
+=
+
+A "hashtable" is theoretically a lazily-filled array of objects of
+length 2**64.  Initially it is full of NULLs.  It's obviously
+implemented as a dictionary in which NULL objects are not needed.
+
+The only operations on a hashtable are reading or writing an object at
+a given index.
+
+There are two markers for every index (a read and a write marker).
+This is unlike regular arrays, which have only two markers in total.
+
+
+Implementation
+--
+
+First idea: have the hashtable in raw memory, pointing to "entry"
+objects.  The entry objects themselves point to the user-specified
+objects, and they have the read/write markers.  Every entry object
+itself, once created, stays around.  It is only removed by the next
+major GC if it points to NULL and its read/write markers are not set
+in any currently-running transaction.
+*/
+
+
+typedef TLPREFIX struct stm_hashtable_entry_s {
+struct object_s header;
+uintptr_t index;
+object_t *object;
+} stm_hashtable_entry_t;
+
+
+#define INITIAL_HASHTABLE_SIZE   8
+#define PERTURB_SHIFT5
+#define RESIZING_LOCK0
+
+typedef struct {
+uintptr_t mask;
+
+/* 'resize_counter' start at an odd value, and is decremented (by
+   6) for every new item put in 'items'.  When it crosses 0, we
+   instead allocate a bigger table and change 'resize_counter' to
+   be a regular pointer to it (which is then even).  The whole
+   structure is immutable then.
+
+   The field 'resize_counter' also works as a write lock: changes
+   go via the intermediate value RESIZING_LOCK (0).
+*/
+uintptr_t resize_counter;
+
+stm_hashtable_entry_t *items[INITIAL_HASHTABLE_SIZE];
+} stm_hashtable_table_t;
+
+#define IS_EVEN(p) (((p) & 1) == 0)
+
+struct stm_hashtable_s {
+stm_hashtable_table_t *table;
+stm_hashtable_table_t initial_table;
+};
+
+
+static inline void init_table(stm_hashtable_table_t *table, uintptr_t 
itemcount)
+{
+table->mask = itemcount - 1;
+table->resize_counter = itemcount * 4 + 1;
+memset(table->items, 0, itemcount * sizeof(stm_hashtable_entry_t *));
+}
+
+stm_hashtable_t *stm_hashtable_create(void)
+{
+stm_hashtable_t *hashtable = malloc(sizeof(stm_hashtable_t));
+assert(hashtable);
+hashtable->table = &hashtable->initial_table;
+init_table(&hashtable->initial_table, INITIAL_HASHTABLE_SIZE);
+return hashtable;
+}
+
+void stm_hashtable_free(stm_hashtable_t *hashtable)
+{
+uintptr_t rc = hashtable->initial_table.resize_counter;
+free(hashtable);
+while (IS_EVEN(rc)) {
+assert(rc != RESIZING_LOCK);
+
+stm_hashtable_table_t *table = (stm_hashtable_table_t *)rc;
+rc = table->resize_counter;
+free(table);
+}
+}
+
+#if 0
+static void stm_compact_hashtable(stm_hashtable_t *hashtable)
+{
+stm_hashtable_table_t *table = hashtable->table;
+assert(!IS_EVEN(table->resize_counter));
+
+if (table != &hashtable->initial_table) {
+uintptr_t rc = hashtable->initial_table.resize_counter;
+while (1) {
+assert(IS_EVEN(rc));
+assert(rc != RESIZING_LOCK);
+
+stm_hashtable_table_t *old_table = (stm_hashtable_table_t *)rc;
+if (old_table == table)
+break;
+rc = old_table->resize_counter;
+free(old_table);
+}
+hashtable->initial_table.resize_counter = (uintptr_t)table;
+}
+if (table->resize_counter < table->mask * 3) {
+uintptr_t j, mask = table->mask;
+uintptr_t rc = table->resize_counter;
+for (j = 0; j <= mask; j++) {
+stm_hashtable_entry_t *e = table->items[j];
+if (e != NULL && e->object == NULL) {
+if (!_stm_was_read_by_anybody(e)) {
+table->items[j] = NULL;
+rc += 6;
+}
+}
+}
+table->resize_counter = rc;
+}
+}
+#endif
+
+#define VOLATILE_HASHTABLE(p)((volatile stm_hashtable_t *)(p))
+#define VOLATILE_TABLE(p)  ((volatile stm_hashtable_table_t *)(p))
+
+static void _insert_clean(stm_hashtable_table_t *table,
+  stm_hashtable_entry_t *entry)
+{
+uintptr_t mask = table->mask;
+uintptr_t i = entry->index & mask;
+if (table->items[i] == NULL) {
+table->items[i] = entry;
+return;
+}
+
+uintptr_t perturb = entry->index;
+while (1) {
+i = (i << 2) + i + perturb + 1;
+i &= mask;
+if (table->items[i] == NULL) {
+table-

[pypy-commit] stmgc hashtable: Next test

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: hashtable
Changeset: r1480:e2b457616c30
Date: 2014-10-18 17:27 +0200
http://bitbucket.org/pypy/stmgc/changeset/e2b457616c30/

Log:Next test

diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
--- a/c7/stm/hashtable.c
+++ b/c7/stm/hashtable.c
@@ -29,10 +29,13 @@
 
 typedef TLPREFIX struct stm_hashtable_entry_s {
 struct object_s header;
+uint32_t userdata;
 uintptr_t index;
 object_t *object;
 } stm_hashtable_entry_t;
 
+uint32_t stm_hashtable_entry_userdata;
+
 
 #define INITIAL_HASHTABLE_SIZE   8
 #define PERTURB_SHIFT5
@@ -219,7 +222,9 @@
 if (rc > 6) {
 entry = (stm_hashtable_entry_t *)
 _stm_allocate_old(sizeof(stm_hashtable_entry_t));
+entry->userdata = stm_hashtable_entry_userdata;
 entry->index = index;
+entry->object = NULL;
 write_fence(); /* make sure 'entry' is fully initialized here */
 table->items[i] = entry;
 write_fence(); /* make sure 'table->items' is written here */
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -508,7 +508,7 @@
 /* Support for light finalizers.  This is a simple version of
finalizers that guarantees not to do anything fancy, like not
resurrecting objects. */
-void (*stmcb_light_finalizer)(object_t *);
+extern void (*stmcb_light_finalizer)(object_t *);
 void stm_enable_light_finalizer(object_t *);
 
 /* Support for regular finalizers.  Unreachable objects with
@@ -525,7 +525,7 @@
transaction.  For older objects, the finalizer is called from a
random thread between regular transactions, in a new custom
transaction. */
-void (*stmcb_finalizer)(object_t *);
+extern void (*stmcb_finalizer)(object_t *);
 object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up);
 
 /* Hashtables.  Keys are 64-bit unsigned integers, values are
@@ -538,6 +538,7 @@
 void stm_hashtable_free(stm_hashtable_t *);
 object_t *stm_hashtable_read(stm_hashtable_t *, uintptr_t key);
 void stm_hashtable_write(stm_hashtable_t *, uintptr_t key, object_t *nvalue);
+extern uint32_t stm_hashtable_entry_userdata;
 
 /*  END  */
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -171,6 +171,7 @@
 void stm_hashtable_free(stm_hashtable_t *);
 object_t *stm_hashtable_read(stm_hashtable_t *, uintptr_t key);
 void stm_hashtable_write(stm_hashtable_t *, uintptr_t key, object_t *nvalue);
+uint32_t stm_hashtable_entry_userdata;
 """)
 
 
@@ -410,6 +411,7 @@
 CARD_SIZE = lib._STM_CARD_SIZE # 16b at least
 NB_SEGMENTS = lib.STM_NB_SEGMENTS
 FAST_ALLOC = lib._STM_FAST_ALLOC
+lib.stm_hashtable_entry_userdata = 42 + HDR + 2 * 8
 
 class Conflict(Exception):
 pass
diff --git a/c7/test/test_hashtable.py b/c7/test/test_hashtable.py
--- a/c7/test/test_hashtable.py
+++ b/c7/test/test_hashtable.py
@@ -12,3 +12,15 @@
 got = lib.stm_hashtable_read(h, index)
 assert got == ffi.NULL
 lib.stm_hashtable_free(h)
+
+def test_set_value(self):
+self.start_transaction()
+h = lib.stm_hashtable_create()
+lp1 = stm_allocate(16)
+lib.stm_hashtable_write(h, 12345678901, lp1)
+assert lib.stm_hashtable_read(h, 12345678901) == lp1
+for i in range(64):
+index = 12345678901 ^ (1 << i)
+assert lib.stm_hashtable_read(h, index) == ffi.NULL
+assert lib.stm_hashtable_read(h, 12345678901) == lp1
+lib.stm_hashtable_free(h)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc hashtable: test and fix

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: hashtable
Changeset: r1481:34dc63f8a1d1
Date: 2014-10-18 17:47 +0200
http://bitbucket.org/pypy/stmgc/changeset/34dc63f8a1d1/

Log:test and fix

diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
--- a/c7/stm/hashtable.c
+++ b/c7/stm/hashtable.c
@@ -220,11 +220,19 @@
item in the current table.
 */
 if (rc > 6) {
-entry = (stm_hashtable_entry_t *)
-_stm_allocate_old(sizeof(stm_hashtable_entry_t));
-entry->userdata = stm_hashtable_entry_userdata;
-entry->index = index;
-entry->object = NULL;
+char *p = 
allocate_outside_nursery_large(sizeof(stm_hashtable_entry_t));
+entry = (stm_hashtable_entry_t *)(p - stm_object_pages);
+
+long j;
+for (j = 0; j <= NB_SEGMENTS; j++) {
+struct stm_hashtable_entry_s *e = (struct stm_hashtable_entry_s *)
+REAL_ADDRESS(get_segment_base(j), entry);
+e->header.stm_flags = GCFLAG_WRITE_BARRIER;
+e->userdata = stm_hashtable_entry_userdata;
+e->index = index;
+e->object = NULL;
+}
+
 write_fence(); /* make sure 'entry' is fully initialized here */
 table->items[i] = entry;
 write_fence(); /* make sure 'table->items' is written here */
diff --git a/c7/test/test_hashtable.py b/c7/test/test_hashtable.py
--- a/c7/test/test_hashtable.py
+++ b/c7/test/test_hashtable.py
@@ -24,3 +24,31 @@
 assert lib.stm_hashtable_read(h, index) == ffi.NULL
 assert lib.stm_hashtable_read(h, 12345678901) == lp1
 lib.stm_hashtable_free(h)
+
+def test_no_conflict(self):
+h = lib.stm_hashtable_create()
+lp1 = stm_allocate_old(16)
+lp2 = stm_allocate_old(16)
+#
+self.start_transaction()
+stm_set_char(lp1, 'A')
+lib.stm_hashtable_write(h, 1234, lp1)
+self.commit_transaction()
+#
+self.start_transaction()
+stm_set_char(lp2, 'B')
+lib.stm_hashtable_write(h, 9991234, lp2)
+#
+self.switch(1)
+self.start_transaction()
+lp1b = lib.stm_hashtable_read(h, 1234)
+assert stm_get_char(lp1b) == 'A'
+assert lp1b == lp1
+self.commit_transaction()
+#
+self.switch(0)
+assert lib.stm_hashtable_read(h, 9991234) == lp2
+assert stm_get_char(lp2) == 'B'
+assert lib.stm_hashtable_read(h, 1234) == lp1
+lib.stm_hashtable_write(h, 1234, ffi.NULL)
+self.commit_transaction()
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc hashtable: Add a test about hashtable conflicts

2014-10-18 Thread arigo
Author: Armin Rigo 
Branch: hashtable
Changeset: r1482:40201225092d
Date: 2014-10-18 17:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/40201225092d/

Log:Add a test about hashtable conflicts

diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -170,7 +170,9 @@
 stm_hashtable_t *stm_hashtable_create(void);
 void stm_hashtable_free(stm_hashtable_t *);
 object_t *stm_hashtable_read(stm_hashtable_t *, uintptr_t key);
-void stm_hashtable_write(stm_hashtable_t *, uintptr_t key, object_t *nvalue);
+bool _check_hashtable_read(stm_hashtable_t *, uintptr_t key);
+object_t *hashtable_read_result;
+bool _check_hashtable_write(stm_hashtable_t *, uintptr_t key, object_t 
*nvalue);
 uint32_t stm_hashtable_entry_userdata;
 """)
 
@@ -247,6 +249,18 @@
 CHECKED(stm_become_globally_unique_transaction(tl, "TESTGUT"));
 }
 
+object_t *hashtable_read_result;
+
+bool _check_hashtable_read(stm_hashtable_t *h, uintptr_t key)
+{
+CHECKED(hashtable_read_result = stm_hashtable_read(h, key));
+}
+
+bool _check_hashtable_write(stm_hashtable_t *h, uintptr_t key, object_t 
*nvalue)
+{
+CHECKED(stm_hashtable_write(h, key, nvalue));
+}
+
 #undef CHECKED
 
 
@@ -566,7 +580,6 @@
 
 
 
-
 SHADOWSTACK_LENGTH = 1000
 _keepalive = weakref.WeakKeyDictionary()
 
diff --git a/c7/test/test_hashtable.py b/c7/test/test_hashtable.py
--- a/c7/test/test_hashtable.py
+++ b/c7/test/test_hashtable.py
@@ -2,53 +2,86 @@
 import random
 import py
 
+
+class StmHashTable(object):
+def __init__(self):
+self.h = lib.stm_hashtable_create()
+
+def free(self):
+lib.stm_hashtable_free(self.h)
+
+def __getitem__(self, key):
+res = lib._check_hashtable_read(self.h, key)
+if res:
+raise Conflict
+return lib.hashtable_read_result
+
+def __setitem__(self, key, nvalue):
+res = lib._check_hashtable_write(self.h, key, nvalue)
+if res:
+raise Conflict
+
+
 class TestHashtable(BaseTest):
 
 def test_empty(self):
 self.start_transaction()
-h = lib.stm_hashtable_create()
+h = StmHashTable()
 for i in range(100):
 index = random.randrange(0, 1<<64)
-got = lib.stm_hashtable_read(h, index)
+got = h[index]
 assert got == ffi.NULL
-lib.stm_hashtable_free(h)
+h.free()
 
 def test_set_value(self):
 self.start_transaction()
-h = lib.stm_hashtable_create()
+h = StmHashTable()
 lp1 = stm_allocate(16)
-lib.stm_hashtable_write(h, 12345678901, lp1)
-assert lib.stm_hashtable_read(h, 12345678901) == lp1
+h[12345678901] = lp1
+assert h[12345678901] == lp1
 for i in range(64):
 index = 12345678901 ^ (1 << i)
-assert lib.stm_hashtable_read(h, index) == ffi.NULL
-assert lib.stm_hashtable_read(h, 12345678901) == lp1
-lib.stm_hashtable_free(h)
+assert h[index] == ffi.NULL
+assert h[12345678901] == lp1
+h.free()
 
 def test_no_conflict(self):
-h = lib.stm_hashtable_create()
+h = StmHashTable()
 lp1 = stm_allocate_old(16)
 lp2 = stm_allocate_old(16)
 #
 self.start_transaction()
 stm_set_char(lp1, 'A')
-lib.stm_hashtable_write(h, 1234, lp1)
+h[1234] = lp1
 self.commit_transaction()
 #
 self.start_transaction()
 stm_set_char(lp2, 'B')
-lib.stm_hashtable_write(h, 9991234, lp2)
+h[9991234] = lp2
 #
 self.switch(1)
 self.start_transaction()
-lp1b = lib.stm_hashtable_read(h, 1234)
+lp1b = h[1234]
 assert stm_get_char(lp1b) == 'A'
 assert lp1b == lp1
 self.commit_transaction()
 #
 self.switch(0)
-assert lib.stm_hashtable_read(h, 9991234) == lp2
+assert h[9991234] == lp2
 assert stm_get_char(lp2) == 'B'
-assert lib.stm_hashtable_read(h, 1234) == lp1
-lib.stm_hashtable_write(h, 1234, ffi.NULL)
+assert h[1234] == lp1
+h[1234] = ffi.NULL
 self.commit_transaction()
+h.free()
+
+def test_conflict(self):
+h = StmHashTable()
+lp1 = stm_allocate_old(16)
+lp2 = stm_allocate_old(16)
+#
+self.start_transaction()
+h[1234] = lp1
+#
+self.switch(1)
+self.start_transaction()
+py.test.raises(Conflict, "h[1234] = lp2")
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-incminimark-pinning: Merge default into gc-incminimark-pinning.

2014-10-18 Thread groggi
Author: Gregor Wegberg 
Branch: gc-incminimark-pinning
Changeset: r74012:a541092c6e2f
Date: 2014-10-18 19:24 +0200
http://bitbucket.org/pypy/pypy/changeset/a541092c6e2f/

Log:Merge default into gc-incminimark-pinning.

This is a first step merging the current incminimark (without zero
filling nursery). Still a lot of tests to pass. However, its a
start.

diff too long, truncating to 2000 out of 16865 lines

diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -3,8 +3,8 @@
 
 Except when otherwise stated (look for LICENSE files in directories or
 information at the beginning of each file) all software and documentation in
-the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', and 'lib_pypy'
-directories is licensed as follows: 
+the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', 'lib_pypy',
+'py', and '_pytest' directories is licensed as follows: 
 
 The MIT License
 
@@ -367,3 +367,43 @@
 Detailed license information is contained in the NOTICE file in the
 directory.
 
+
+Licenses and Acknowledgements for Incorporated Software
+===
+
+This section is an incomplete, but growing list of licenses and
+acknowledgements for third-party software incorporated in the PyPy
+distribution.
+
+License for 'Tcl/Tk'
+
+
+This copy of PyPy contains library code that may, when used, result in
+the Tcl/Tk library to be loaded.  PyPy also includes code that may be
+regarded as being a copy of some parts of the Tcl/Tk header files.
+You may see a copy of the License for Tcl/Tk in the file
+`lib_pypy/_tkinter/license.terms` included here.
+
+License for 'bzip2'
+---
+
+This copy of PyPy may be linked (dynamically or statically) with the
+bzip2 library.  You may see a copy of the License for bzip2/libbzip2 at
+
+http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html
+
+License for 'openssl'
+-
+
+This copy of PyPy may be linked (dynamically or statically) with the
+openssl library.  You may see a copy of the License for OpenSSL at
+
+https://www.openssl.org/source/license.html
+
+License for 'gdbm'
+--
+
+The gdbm module includes code from gdbm.h, which is distributed under
+the terms of the GPL license version 2 or any later version.  Thus the
+gdbm module, provided in the file lib_pypy/gdbm.py, is redistributed
+under the terms of the GPL license as well.
diff --git a/lib-python/2.7/test/test_select.py 
b/lib-python/2.7/test/test_select.py
--- a/lib-python/2.7/test/test_select.py
+++ b/lib-python/2.7/test/test_select.py
@@ -57,7 +57,17 @@
 del a[-1]
 return sys.__stdout__.fileno()
 a[:] = [F()] * 10
-self.assertEqual(select.select([], a, []), ([], a[:5], []))
+result = select.select([], a, [])
+# CPython: 'a' ends up with 5 items, because each fileno()
+# removes an item and at the middle the iteration stops.
+# PyPy: 'a' ends up empty, because the iteration is done on
+# a copy of the original list: fileno() is called 10 times.
+if test_support.check_impl_detail(cpython=True):
+self.assertEqual(len(result[1]), 5)
+self.assertEqual(len(a), 5)
+if test_support.check_impl_detail(pypy=True):
+self.assertEqual(len(result[1]), 10)
+self.assertEqual(len(a), 0)
 
 def test_main():
 test_support.run_unittest(SelectTestCase)
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -1242,7 +1242,7 @@
 (other._hour, other._minute, other._second,
  other._microsecond))
 if myoff is None or otoff is None:
-raise TypeError("cannot compare naive and aware times")
+raise TypeError("can't compare offset-naive and offset-aware 
times")
 myhhmm = self._hour * 60 + self._minute - myoff
 othhmm = other._hour * 60 + other._minute - otoff
 return _cmp((myhhmm, self._second, self._microsecond),
@@ -1838,7 +1838,7 @@
  other._hour, other._minute, other._second,
  other._microsecond))
 if myoff is None or otoff is None:
-raise TypeError("cannot compare naive and aware datetimes")
+raise TypeError("can't compare offset-naive and offset-aware 
datetimes")
 # XXX What follows could be done more efficiently...
 diff = self - other # this will take offsets into account
 if diff.days < 0:
@@ -1885,7 +1885,7 @@
 if myoff == otoff:
 return base
 if myoff is None or otoff is None:
-raise TypeError("cannot mix naive and timezone-aware time")
+raise TypeError("can't subtract offset-naive and offset-aware 
datetimes")
 return base + timedelta(minutes = otoff-myoff)
 
 def __hash__(self):
diff --gi

[pypy-commit] pypy gc-incminimark-pinning: passing gc/test/test_object_pinning tests, except skipped ones

2014-10-18 Thread groggi
Author: Gregor Wegberg 
Branch: gc-incminimark-pinning
Changeset: r74013:fc3eef4065bc
Date: 2014-10-18 19:34 +0200
http://bitbucket.org/pypy/pypy/changeset/fc3eef4065bc/

Log:passing gc/test/test_object_pinning tests, except skipped ones

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -723,9 +723,10 @@
 "Too many pinned objects?")
 #
 result = self.nursery_free
-if self.nursery_free + totalsize <= self.nursery + 
self.nursery_size:
+if self.nursery_free + totalsize <= self.nursery_top:
 self.nursery_free = result + totalsize
-ll_assert(self.nursery_free <= self.nursery + 
self.nursery_size, "nursery overflow")
+ll_assert(self.nursery_free <= self.nursery_top, "nursery 
overflow")
+break
 #
 #
 if self.debug_tiny_nursery >= 0:   # for debugging
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-incminimark-pinning: passing all object pinning specific GC tests again

2014-10-18 Thread groggi
Author: Gregor Wegberg 
Branch: gc-incminimark-pinning
Changeset: r74014:26934ad677e7
Date: 2014-10-18 19:46 +0200
http://bitbucket.org/pypy/pypy/changeset/26934ad677e7/

Log:passing all object pinning specific GC tests again

diff --git a/rpython/memory/gc/test/test_object_pinning.py 
b/rpython/memory/gc/test/test_object_pinning.py
--- a/rpython/memory/gc/test/test_object_pinning.py
+++ b/rpython/memory/gc/test/test_object_pinning.py
@@ -636,7 +636,6 @@
 
 
 def test_pin_nursery_top_scenario1(self):
-py.test.skip("nursery no longer zeros, test needs to be rewritten")
 ptr1 = self.malloc(T)
 adr1 = llmemory.cast_ptr_to_adr(ptr1)
 ptr1.someInt = 101
@@ -658,9 +657,9 @@
 # scenario: no minor collection happened, only three mallocs
 # and pins
 #
-# +- nursery   nursery_real_top -+
-# |  |
-# v  v
+# +- nursery
+# |
+# v
 # ++++-...---+
 # | pinned | pinned | pinned | empty |
 # ++++-...---+
@@ -671,11 +670,9 @@
 #
 assert adr3 < self.gc.nursery_free
 assert self.gc.nursery_free < self.gc.nursery_top
-assert self.gc.nursery_top == self.gc.nursery_real_top
 
 
 def test_pin_nursery_top_scenario2(self):
-py.test.skip("nursery no longer zeros, test needs to be rewritten")
 ptr1 = self.malloc(T)
 adr1 = llmemory.cast_ptr_to_adr(ptr1)
 ptr1.someInt = 101
@@ -696,9 +693,9 @@
 
 # scenario: after first GC minor collection
 #
-# +- nursery   nursery_real_top -+
-# |  |
-# v  v
+# +- nursery
+# |
+# v
 # ++++-...---+
 # | pinned | pinned | pinned | empty |
 # ++++-...---+
@@ -712,11 +709,9 @@
 assert self.gc.nursery_free == self.gc.nursery_top
 assert self.gc.nursery_top == self.gc.nursery
 assert self.gc.nursery_top < adr3
-assert adr3 < self.gc.nursery_real_top
 
 
 def test_pin_nursery_top_scenario3(self):
-py.test.skip("nursery no longer zeros, test needs to be rewritten")
 ptr1 = self.malloc(T)
 adr1 = llmemory.cast_ptr_to_adr(ptr1)
 ptr1.someInt = 101
@@ -738,9 +733,9 @@
 # scenario: after unpinning first object and a minor
 # collection
 #
-# +- nursery   nursery_real_top -+
-# |  |
-# v  v
+# +- nursery
+# |
+# v
 # ++++-...---+
 # | empty  | pinned | pinned | empty |
 # ++++-...---+
@@ -755,11 +750,9 @@
 assert self.gc.nursery_free == self.gc.nursery
 assert self.gc.nursery_top > self.gc.nursery_free
 assert self.gc.nursery_top < adr2
-assert adr3 < self.gc.nursery_real_top
 
 
 def test_pin_nursery_top_scenario4(self):
-py.test.skip("nursery no longer zeros, test needs to be rewritten")
 ptr1 = self.malloc(T)
 adr1 = llmemory.cast_ptr_to_adr(ptr1)
 ptr1.someInt = 101
@@ -781,9 +774,9 @@
 # scenario: after unpinning first & second object and a minor
 # collection
 #
-# +- nursery   nursery_real_top -+
-# |  |
-# v  v
+# +- nursery
+# |
+# v
 # +-++-...---+
 # | empty   | pinned | empty |
 # +-++-...---+
@@ -799,11 +792,9 @@
 assert self.gc.nursery_free == self.gc.nursery
 assert self.gc.nursery_free < self.gc.nursery_top
 assert self.gc.nursery_top < adr3
-assert adr3 < self.gc.nursery_real_top
 
 
 def test_pin_nursery_top_scenario5(self):
-py.test.skip("nursery no longer zeros, test needs to be rewritten")
 ptr1 = self.malloc(T)
 adr1 = llmemory.cast_ptr_to_adr(ptr1)
 ptr1.someInt = 101
@@ -825,9 +816,9 @@
 # scenario: no minor collection happened, only three mallocs
 # and pins
 #
-# +- nursery   nursery_real_top -+
-# |   

[pypy-commit] pypy online-transforms: refactor handling of method objects in bk.immutablevalue()

2014-10-18 Thread rlamy
Author: Ronan Lamy 
Branch: online-transforms
Changeset: r74015:ca0bb5571fc7
Date: 2014-10-19 04:59 +0100
http://bitbucket.org/pypy/pypy/changeset/ca0bb5571fc7/

Log:refactor handling of method objects in bk.immutablevalue()

diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -35,6 +35,14 @@
 CONTAINERS_S = [SomeList, SomeDict, SomeOrderedDict, SomeTuple]
 _cls2Some = {cls.knowntype: cls for cls in CONTAINERS_S}
 
+
+if '__pypy__' in sys.modules:
+def is_user_function(func):
+return (isinstance(func, types.FunctionType) and
+isinstance(func.func_code, types.CodeType))
+else:
+is_user_function = inspect.isfunction
+
 class Bookkeeper(object):
 """The log of choices that have been made while analysing the operations.
 It ensures that the same 'choice objects' will be returned if we ask
@@ -215,10 +223,6 @@
 def immutablevalue(self, x):
 """The most precise SomeValue instance that contains the
 immutable value x."""
-# convert unbound methods to the underlying function
-if hasattr(x, 'im_self') and x.im_self is None:
-x = x.im_func
-assert not hasattr(x, 'im_self')
 tp = type(x)
 if issubclass(tp, Symbolic): # symbolic constants support
 result = x.annotation()
@@ -310,19 +314,15 @@
 elif tp is type:
 result = SomeConstantType(x, self)
 elif callable(x):
-if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
-# on top of PyPy, for cases like 'l.append' where 'l' is a
-# global constant list, the find_method() returns non-None
-s_self = self.immutablevalue(x.im_self)
-result = s_self.find_method(x.im_func.__name__)
-elif hasattr(x, '__self__') and x.__self__ is not None:
-# for cases like 'l.append' where 'l' is a global constant list
-s_self = self.immutablevalue(x.__self__)
-result = s_self.find_method(x.__name__)
-assert result is not None
-elif hasattr(x, '__objclass__'):
-cls_s = self.annotationclass(x.__objclass__)
-result = cls_s.find_unboundmethod(x.__name__)
+if hasattr(x, '__self__'):
+if x.__self__ is not None:
+# bound instance method
+s_self = self.immutablevalue(x.__self__)
+result = s_self.find_method(x.__name__)
+else:
+# unbound method
+cls_s = self.annotationclass(x.im_class)
+result = cls_s.find_unboundmethod(x.__name__)
 else:
 result = None
 if result is None:
@@ -358,7 +358,7 @@
 try:
 return self.descs[pyobj]
 except KeyError:
-if isinstance(pyobj, types.FunctionType):
+if is_user_function(pyobj):
 result = description.FunctionDesc(self, pyobj)
 elif isinstance(pyobj, (type, types.ClassType)):
 if pyobj is object:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit