[pypy-commit] stmgc default: first random-test version in C. may have some bugs..

2013-06-19 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r195:bbf01c89fe52
Date: 2013-06-19 14:32 +0200
http://bitbucket.org/pypy/stmgc/changeset/bbf01c89fe52/

Log:first random-test version in C. may have some bugs..

diff --git a/c4/demo_random.c b/c4/demo_random.c
new file mode 100644
--- /dev/null
+++ b/c4/demo_random.c
@@ -0,0 +1,316 @@
+#include stdlib.h
+#include stdio.h
+#include assert.h
+#include pthread.h
+#include semaphore.h
+#include time.h
+
+#include stmgc.h
+#include fprintcolor.h
+
+
+#define NUMTHREADS 4
+#define STEPS 10
+#define NUMROOTS 10
+#define PREBUILT 3
+#define MAXROOTS 1000
+#define SHARED_ROOTS 5
+
+
+// SUPPORT
+#define GCTID_STRUCT_ROOT 123
+
+struct root {
+struct stm_object_s hdr;
+long value;
+struct root *next;
+};
+typedef struct root * rootptr;
+
+size_t stmcb_size(gcptr ob)
+{
+assert(stm_get_tid(ob) == GCTID_STRUCT_ROOT);
+return sizeof(struct root);
+}
+void stmcb_trace(gcptr ob, void visit(gcptr *))
+{
+rootptr n;
+assert(stm_get_tid(ob) == GCTID_STRUCT_ROOT);
+n = (rootptr)ob;
+visit((gcptr *)n-next);
+}
+
+// global and per-thread-data
+time_t default_seed;
+gcptr shared_roots[SHARED_ROOTS];
+__thread unsigned int thread_seed = 0;
+__thread gcptr roots[MAXROOTS];
+__thread gcptr roots_outside_perform[MAXROOTS];
+__thread gcptr current_root = 0;
+__thread int num_roots = 0;
+__thread int num_roots_outside_perform = 0;
+__thread int steps_left;
+__thread int interruptible = 0;
+
+
+// helper functions
+int get_rand(int max)
+{
+return (int)(rand_r(thread_seed) % (unsigned int)max);
+}
+
+void copy_roots(gcptr *from, gcptr *to)
+{
+int i;
+for (i = 0; i  num_roots; i++)
+*(to++) = *(from++);
+}
+
+gcptr allocate_pseudoprebuilt(size_t size, int tid)
+{
+gcptr x = calloc(1, size);
+x-h_tid = PREBUILT_FLAGS | tid;
+x-h_revision = PREBUILT_REVISION;
+return x;
+}
+
+void push_roots()
+{
+int i;
+for (i = 0; i  num_roots; i++)
+stm_push_root(roots[i]);
+}
+
+void pop_roots()
+{
+int i;
+for (i = num_roots - 1; i = 0; i--)
+roots[i] = stm_pop_root();
+}
+
+void del_root(int idx)
+{
+int i;
+for (i = idx; i  num_roots - 1; i++)
+roots[i] = roots[i + 1];
+}
+
+gcptr allocate_root(size_t size, int tid)
+{
+gcptr r;
+push_roots();
+r = stm_allocate(size, tid);
+pop_roots();
+return r;
+}
+
+
+
+// THREAD TESTER
+int interruptible_callback(gcptr arg1, int retry_counter);
+int run_me();
+void transaction_break();
+
+void setup_thread()
+{
+int i;
+thread_seed = default_seed;
+steps_left = STEPS;
+interruptible = 0;
+
+num_roots = PREBUILT + NUMROOTS;
+for (i = 0; i  PREBUILT; i++) {
+roots[i] = allocate_pseudoprebuilt(sizeof(struct root), 
+   GCTID_STRUCT_ROOT);
+}
+for (i = PREBUILT; i  PREBUILT + NUMROOTS; i++) {
+roots[i] = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+}
+
+}
+
+gcptr do_step(gcptr p)
+{
+fprintf(stdout, #);
+
+rootptr w_r, w_sr;
+gcptr _r, _sr;
+int num, k;
+
+num = get_rand(num_roots);
+_r = roots[num];
+
+num = get_rand(SHARED_ROOTS);
+_sr = shared_roots[num];
+
+k = get_rand(14);
+
+if (!p) // some parts expect it to be != 0
+p = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+
+switch (k) {
+case 0: // remove a root
+if (num  0)
+del_root(num);
+break;
+case 1: // set 'p' to point to a root
+if (_r)
+p = _r;
+break;
+case 2: // add 'p' to roots
+if (num_roots  MAXROOTS)
+roots[num_roots++] = p;
+break;
+case 3: // allocate fresh 'p'
+p = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+break;
+case 4: // set 'p' as *next in one of the roots
+w_r = (rootptr)stm_write_barrier(_r);
+// XXX: do I have to read_barrier(p)?
+w_r-next = (struct root*)p;
+break;
+case 5:  // read and validate 'p'
+stm_read_barrier(p);
+break;
+case 6: // transaction break
+if (interruptible)
+return -1; // break current
+transaction_break();
+p = NULL;
+break;
+case 7: // only do a stm_write_barrier
+p = stm_write_barrier(p);
+break;
+case 8:
+p = (gcptr)(((rootptr)stm_read_barrier(p))-next);
+break;
+case 9: // XXX: rare events
+break;
+case 10: // only do a stm_read_barrier
+p = stm_read_barrier(p);
+break;
+case 11:
+stm_read_barrier(_sr);
+break;
+case 12:
+stm_write_barrier(_sr);
+break;
+case 13:
+w_sr = stm_write_barrier(_sr);
+w_sr-next = shared_roots[get_rand(SHARED_ROOTS)];
+default:
+break;
+}
+return p;
+}
+
+
+void transaction_break()
+{
+push_roots();
+

[pypy-commit] stmgc default: add demo2 (bubble sort)

2013-06-19 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r194:716b7629c9cd
Date: 2013-06-19 11:20 +0200
http://bitbucket.org/pypy/stmgc/changeset/716b7629c9cd/

Log:add demo2 (bubble sort)

diff --git a/c4/demo2.c b/c4/demo2.c
new file mode 100644
--- /dev/null
+++ b/c4/demo2.c
@@ -0,0 +1,218 @@
+#include stdlib.h
+#include stdio.h
+#include assert.h
+#include pthread.h
+#include semaphore.h
+
+#include stmgc.h
+#include fprintcolor.h
+
+
+#define LIST_LENGTH 500
+#define NUMTHREADS  4
+
+
+#define GCTID_STRUCT_NODE 123
+
+struct node {
+struct stm_object_s hdr;
+long value;
+struct node *next;
+};
+typedef struct node * nodeptr;
+
+size_t stmcb_size(gcptr ob)
+{
+assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
+return sizeof(struct node);
+}
+
+void stmcb_trace(gcptr ob, void visit(gcptr *))
+{
+nodeptr n;
+assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
+n = (nodeptr)ob;
+visit((gcptr *)n-next);
+}
+
+
+struct node global_chained_list = {
+{ GCTID_STRUCT_NODE | PREBUILT_FLAGS, PREBUILT_REVISION },
+-1,
+NULL,
+};
+
+
+long check_sorted()
+{
+nodeptr r_n;
+long prev, sum;
+r_n = (nodeptr)stm_read_barrier((gcptr)global_chained_list);
+assert(r_n-value == -1);
+
+prev = -1;
+sum = 0;
+while (r_n-next) {
+r_n = (nodeptr)stm_read_barrier((gcptr)r_n-next);
+sum += r_n-value;
+
+if (prev = r_n-value)
+return -1;
+
+prev = r_n-value;
+}
+
+return sum;
+}
+
+void swap_nodes(nodeptr prev, nodeptr current, nodeptr next)
+{
+nodeptr w_prev, w_current, w_next;
+w_prev = (nodeptr)stm_write_barrier((gcptr)prev);
+w_current = (nodeptr)stm_write_barrier((gcptr)current);
+w_next = (nodeptr)stm_write_barrier((gcptr)next);
+
+w_prev-next = w_next;
+w_current-next = w_next-next;
+w_next-next = w_current;
+}
+
+int bubble_run(gcptr arg1, int retry_counter)
+{
+nodeptr r_prev, r_current, r_next, tmp;
+
+r_prev = (nodeptr)stm_read_barrier(arg1);
+r_current = (nodeptr)stm_read_barrier((gcptr)r_prev-next);
+r_next = (nodeptr)stm_read_barrier((gcptr)r_current-next);
+
+while (r_next) {
+if (r_next-value  r_current-value) {
+// swap current and next
+swap_nodes(r_prev, r_current, r_next);   
+fprintf(stdout, #);
+
+// needs read barriers, because of write barriers in swap_nodes
+r_prev = (struct node*)stm_read_barrier((gcptr)r_prev);
+tmp = r_current;
+r_current = (struct node*)stm_read_barrier((gcptr)r_next);
+r_next = (struct node*)stm_read_barrier((gcptr)tmp);
+}
+// results from consecutive read_barriers can differ. needs Ptr_Eq()
+/* assert(stm_read_barrier((gcptr)r_prev-next) == r_current */
+/*   stm_read_barrier((gcptr)r_current-next) == r_next); */
+// for now:
+assert(((nodeptr)stm_read_barrier((gcptr)r_prev-next))-value 
+   == r_current-value
+
+   ((nodeptr)stm_read_barrier((gcptr)r_current-next))-value
+   == r_next-value);
+
+r_prev = r_current;
+r_current = r_next;
+r_next = r_next-next;
+if (r_next != NULL)
+r_next = (nodeptr)stm_read_barrier((gcptr)r_next);
+}
+
+
+return 0;
+}
+
+
+static sem_t done;
+
+static int thr_mynum = 0;
+
+void *demo2(void *arg)
+{
+
+int status;
+stm_initialize();
+
+thr_mynum++;   /* protected by being inevitable here */
+fprintf(stderr, THREAD STARTING\n);
+
+
+while (check_sorted() == -1) {
+stm_perform_transaction((gcptr)global_chained_list, bubble_run);
+}
+
+stm_finalize();
+
+status = sem_post(done);
+assert(status == 0);
+return NULL;
+}
+
+void final_check(void)
+{
+long sum;
+
+stm_initialize();
+
+sum = check_sorted();
+
+// little Gauss:
+assert(sum == (1 + LIST_LENGTH) * (LIST_LENGTH / 2));
+
+stm_finalize();
+printf(check ok\n);
+}
+
+
+void newthread(void*(*func)(void*), void *arg)
+{
+pthread_t th;
+int status = pthread_create(th, NULL, func, arg);
+assert(status == 0);
+pthread_detach(th);
+printf(started new thread\n);
+}
+
+
+/* initialize list with values in decreasing order */
+void setup_list()
+{
+int i;
+nodeptr w_newnode, w_prev;
+stm_initialize();
+
+w_prev = global_chained_list;
+for (i = 0; i  LIST_LENGTH; i++) {
+stm_push_root((gcptr)w_prev);
+w_newnode = (nodeptr)stm_allocate(sizeof(struct node),
+  GCTID_STRUCT_NODE);
+w_prev = (nodeptr)stm_pop_root();
+w_newnode-value = LIST_LENGTH - i;
+w_newnode-next = NULL;
+
+w_prev = (nodeptr)stm_write_barrier((gcptr)w_prev);
+w_prev-next = 

[pypy-commit] stmgc default: demo_random: thread locals - thread descriptor

2013-06-19 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r196:8d3cf9f0c450
Date: 2013-06-19 14:48 +0200
http://bitbucket.org/pypy/stmgc/changeset/8d3cf9f0c450/

Log:demo_random: thread locals - thread descriptor

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -40,29 +40,33 @@
 visit((gcptr *)n-next);
 }
 
+
 // global and per-thread-data
 time_t default_seed;
 gcptr shared_roots[SHARED_ROOTS];
-__thread unsigned int thread_seed = 0;
-__thread gcptr roots[MAXROOTS];
-__thread gcptr roots_outside_perform[MAXROOTS];
-__thread gcptr current_root = 0;
-__thread int num_roots = 0;
-__thread int num_roots_outside_perform = 0;
-__thread int steps_left;
-__thread int interruptible = 0;
+struct thread_data {
+unsigned int thread_seed;
+gcptr roots[MAXROOTS];
+gcptr roots_outside_perform[MAXROOTS];
+gcptr current_root;
+int num_roots;
+int num_roots_outside_perform;
+int steps_left;
+int interruptible;
+};
+__thread struct thread_data td;
 
 
 // helper functions
 int get_rand(int max)
 {
-return (int)(rand_r(thread_seed) % (unsigned int)max);
+return (int)(rand_r(td.thread_seed) % (unsigned int)max);
 }
 
-void copy_roots(gcptr *from, gcptr *to)
+void copy_roots(gcptr *from, gcptr *to, int num)
 {
 int i;
-for (i = 0; i  num_roots; i++)
+for (i = 0; i  num; i++)
 *(to++) = *(from++);
 }
 
@@ -77,22 +81,22 @@
 void push_roots()
 {
 int i;
-for (i = 0; i  num_roots; i++)
-stm_push_root(roots[i]);
+for (i = 0; i  td.num_roots; i++)
+stm_push_root(td.roots[i]);
 }
 
 void pop_roots()
 {
 int i;
-for (i = num_roots - 1; i = 0; i--)
-roots[i] = stm_pop_root();
+for (i = td.num_roots - 1; i = 0; i--)
+td.roots[i] = stm_pop_root();
 }
 
 void del_root(int idx)
 {
 int i;
-for (i = idx; i  num_roots - 1; i++)
-roots[i] = roots[i + 1];
+for (i = idx; i  td.num_roots - 1; i++)
+td.roots[i] = td.roots[i + 1];
 }
 
 gcptr allocate_root(size_t size, int tid)
@@ -114,17 +118,17 @@
 void setup_thread()
 {
 int i;
-thread_seed = default_seed;
-steps_left = STEPS;
-interruptible = 0;
+td.thread_seed = default_seed;
+td.steps_left = STEPS;
+td.interruptible = 0;
 
-num_roots = PREBUILT + NUMROOTS;
+td.num_roots = PREBUILT + NUMROOTS;
 for (i = 0; i  PREBUILT; i++) {
-roots[i] = allocate_pseudoprebuilt(sizeof(struct root), 
-   GCTID_STRUCT_ROOT);
+td.roots[i] = allocate_pseudoprebuilt(sizeof(struct root), 
+  GCTID_STRUCT_ROOT);
 }
 for (i = PREBUILT; i  PREBUILT + NUMROOTS; i++) {
-roots[i] = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+td.roots[i] = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
 }
 
 }
@@ -137,8 +141,8 @@
 gcptr _r, _sr;
 int num, k;
 
-num = get_rand(num_roots);
-_r = roots[num];
+num = get_rand(td.num_roots);
+_r = td.roots[num];
 
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
@@ -158,8 +162,8 @@
 p = _r;
 break;
 case 2: // add 'p' to roots
-if (num_roots  MAXROOTS)
-roots[num_roots++] = p;
+if (td.num_roots  MAXROOTS)
+td.roots[td.num_roots++] = p;
 break;
 case 3: // allocate fresh 'p'
 p = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
@@ -173,8 +177,8 @@
 stm_read_barrier(p);
 break;
 case 6: // transaction break
-if (interruptible)
-return -1; // break current
+if (td.interruptible)
+return (gcptr)-1; // break current
 transaction_break();
 p = NULL;
 break;
@@ -196,8 +200,8 @@
 stm_write_barrier(_sr);
 break;
 case 13:
-w_sr = stm_write_barrier(_sr);
-w_sr-next = shared_roots[get_rand(SHARED_ROOTS)];
+w_sr = (rootptr)stm_write_barrier(_sr);
+w_sr-next = (rootptr)shared_roots[get_rand(SHARED_ROOTS)];
 default:
 break;
 }
@@ -208,32 +212,32 @@
 void transaction_break()
 {
 push_roots();
-interruptible = 1;
+td.interruptible = 1;
 
-copy_roots(roots, roots_outside_perform);
-num_roots_outside_perform = num_roots;
+copy_roots(td.roots, td.roots_outside_perform, td.num_roots);
+td.num_roots_outside_perform = td.num_roots;
 
 stm_perform_transaction(NULL, interruptible_callback);
 
-num_roots = num_roots_outside_perform;
-copy_roots(roots_outside_perform, roots);
+td.num_roots = td.num_roots_outside_perform;
+copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
 
-interruptible = 0;
+td.interruptible = 0;
 pop_roots();
 }
 
 
 int interruptible_callback(gcptr arg1, int retry_counter)
 {
-num_roots = num_roots_outside_perform;
-

[pypy-commit] stmgc default: demo_random: remove ambiguous naming

2013-06-19 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r197:661b7c5a26c9
Date: 2013-06-19 14:54 +0200
http://bitbucket.org/pypy/stmgc/changeset/661b7c5a26c9/

Log:demo_random: remove ambiguous naming

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -18,25 +18,25 @@
 
 
 // SUPPORT
-#define GCTID_STRUCT_ROOT 123
+#define GCTID_STRUCT_NODE 123
 
-struct root {
+struct node {
 struct stm_object_s hdr;
 long value;
-struct root *next;
+struct node *next;
 };
-typedef struct root * rootptr;
+typedef struct node * nodeptr;
 
 size_t stmcb_size(gcptr ob)
 {
-assert(stm_get_tid(ob) == GCTID_STRUCT_ROOT);
-return sizeof(struct root);
+assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
+return sizeof(struct node);
 }
 void stmcb_trace(gcptr ob, void visit(gcptr *))
 {
-rootptr n;
-assert(stm_get_tid(ob) == GCTID_STRUCT_ROOT);
-n = (rootptr)ob;
+nodeptr n;
+assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
+n = (nodeptr)ob;
 visit((gcptr *)n-next);
 }
 
@@ -99,7 +99,7 @@
 td.roots[i] = td.roots[i + 1];
 }
 
-gcptr allocate_root(size_t size, int tid)
+gcptr allocate_node(size_t size, int tid)
 {
 gcptr r;
 push_roots();
@@ -124,11 +124,11 @@
 
 td.num_roots = PREBUILT + NUMROOTS;
 for (i = 0; i  PREBUILT; i++) {
-td.roots[i] = allocate_pseudoprebuilt(sizeof(struct root), 
-  GCTID_STRUCT_ROOT);
+td.roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
+  GCTID_STRUCT_NODE);
 }
 for (i = PREBUILT; i  PREBUILT + NUMROOTS; i++) {
-td.roots[i] = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+td.roots[i] = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE);
 }
 
 }
@@ -137,7 +137,7 @@
 {
 fprintf(stdout, #);
 
-rootptr w_r, w_sr;
+nodeptr w_r, w_sr;
 gcptr _r, _sr;
 int num, k;
 
@@ -150,7 +150,7 @@
 k = get_rand(14);
 
 if (!p) // some parts expect it to be != 0
-p = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+p = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE);
 
 switch (k) {
 case 0: // remove a root
@@ -166,12 +166,12 @@
 td.roots[td.num_roots++] = p;
 break;
 case 3: // allocate fresh 'p'
-p = allocate_root(sizeof(struct root), GCTID_STRUCT_ROOT);
+p = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE);
 break;
 case 4: // set 'p' as *next in one of the roots
-w_r = (rootptr)stm_write_barrier(_r);
+w_r = (nodeptr)stm_write_barrier(_r);
 // XXX: do I have to read_barrier(p)?
-w_r-next = (struct root*)p;
+w_r-next = (struct node*)p;
 break;
 case 5:  // read and validate 'p'
 stm_read_barrier(p);
@@ -186,7 +186,7 @@
 p = stm_write_barrier(p);
 break;
 case 8:
-p = (gcptr)(((rootptr)stm_read_barrier(p))-next);
+p = (gcptr)(((nodeptr)stm_read_barrier(p))-next);
 break;
 case 9: // XXX: rare events
 break;
@@ -200,8 +200,8 @@
 stm_write_barrier(_sr);
 break;
 case 13:
-w_sr = (rootptr)stm_write_barrier(_sr);
-w_sr-next = (rootptr)shared_roots[get_rand(SHARED_ROOTS)];
+w_sr = (nodeptr)stm_write_barrier(_sr);
+w_sr-next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)];
 default:
 break;
 }
@@ -300,8 +300,8 @@
 default_seed = time(NULL) / 3600 / 24;
 
 for (i = 0; i  SHARED_ROOTS; i++) {
-shared_roots[i] = allocate_pseudoprebuilt(sizeof(struct root), 
-  GCTID_STRUCT_ROOT);
+shared_roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
+  GCTID_STRUCT_NODE);
 }
 
 status = sem_init(done, 0, 0);
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: demo_random: more checks

2013-06-20 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r199:b2ce4052626c
Date: 2013-06-20 08:40 +0200
http://bitbucket.org/pypy/stmgc/changeset/b2ce4052626c/

Log:demo_random: more checks

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -6,15 +6,19 @@
 #include time.h
 
 #include stmgc.h
+#include stmimpl.h
 #include fprintcolor.h
 
+extern revision_t get_private_rev_num(void);
+
 
 #define NUMTHREADS 4
 #define STEPS 10
-#define NUMROOTS 10
-#define PREBUILT 3
+#define NUMROOTS 10 // per thread
+#define PREBUILT 3 // per thread
 #define MAXROOTS 1000
-#define SHARED_ROOTS 5
+#define SHARED_ROOTS 5 // shared by threads
+
 
 
 // SUPPORT
@@ -58,6 +62,9 @@
 
 
 // helper functions
+int classify(gcptr p);
+void check(gcptr p);
+
 int get_rand(int max)
 {
 return (int)(rand_r(td.thread_seed) % (unsigned int)max);
@@ -81,15 +88,19 @@
 void push_roots()
 {
 int i;
-for (i = 0; i  td.num_roots; i++)
+for (i = 0; i  td.num_roots; i++) {
+check(td.roots[i]);
 stm_push_root(td.roots[i]);
+}
 }
 
 void pop_roots()
 {
 int i;
-for (i = td.num_roots - 1; i = 0; i--)
+for (i = td.num_roots - 1; i = 0; i--) {
 td.roots[i] = stm_pop_root();
+check(td.roots[i]);
+}
 }
 
 void del_root(int idx)
@@ -99,15 +110,117 @@
 td.roots[i] = td.roots[i + 1];
 }
 
-gcptr allocate_node(size_t size, int tid)
+nodeptr allocate_node()
 {
-gcptr r;
+nodeptr r;
 push_roots();
-r = stm_allocate(size, tid);
+r = (nodeptr)stm_allocate(sizeof(struct node), GCTID_STRUCT_NODE);
 pop_roots();
 return r;
 }
 
+int is_shared_prebuilt(gcptr p)
+{
+int i;
+for (i = 0; i  SHARED_ROOTS; i++)
+if (shared_roots[i] == p)
+return 1;
+return 0;
+}
+
+void check_not_free(gcptr p)
+{
+assert(p != NULL);
+assert((p-h_tid  0x) == GCTID_STRUCT_NODE);
+if (is_shared_prebuilt(p))
+assert(p-h_tid  GCFLAG_PREBUILT_ORIGINAL);
+}
+
+void check(gcptr p)
+{
+if (p != NULL) {
+check_not_free(p);
+classify(p); // additional asserts
+}
+}
+
+gcptr read_barrier(gcptr p)
+{
+gcptr r = p;
+if (p != NULL) {
+check(p);
+r = stm_read_barrier(p);
+check(r);
+}
+return r;
+}
+
+gcptr write_barrier(gcptr p)
+{
+gcptr w = p;
+if (p != NULL) {
+check(p);
+w = stm_write_barrier(p);
+check(w);
+}
+return w;
+}
+
+int in_nursery(gcptr obj)
+{
+struct tx_descriptor *d = thread_descriptor;
+int result1 = (d-nursery_base = (char*)obj 
+   ((char*)obj)  d-nursery_end);
+if (obj-h_tid  GCFLAG_OLD) {
+assert(result1 == 0);
+}
+else {
+/* this assert() also fails if obj is in another nursery than
+   the one of the current thread.  This is ok, because we
+   should not see such pointers. */
+assert(result1 == 1);
+}
+return result1;
+}
+
+static const revision_t C_PRIVATE_FROM_PROTECTED = 1;
+static const revision_t C_PRIVATE= 2;
+static const revision_t C_STUB   = 3;
+static const revision_t C_PUBLIC = 4;
+static const revision_t C_BACKUP = 5;
+static const revision_t C_PROTECTED  = 6;
+int classify(gcptr p)
+{
+int priv_from_prot = (p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) != 0;
+int private_other = p-h_revision == get_private_rev_num();
+int public = (p-h_tid  GCFLAG_PUBLIC) != 0;
+int backup = (p-h_tid  GCFLAG_BACKUP_COPY) != 0;
+int stub = (p-h_tid  GCFLAG_STUB) != 0;
+assert(priv_from_prot + private_other + public + backup = 1);
+assert(public || !stub);
+
+if (priv_from_prot)
+return C_PRIVATE_FROM_PROTECTED;
+if (private_other)
+return C_PRIVATE;
+if (public) {
+if (stub) {
+assert(!in_nursery(p));
+}
+else {
+if (in_nursery(p)) {
+assert(p-h_tid  GCFLAG_NURSERY_MOVED);
+assert(!(p-h_revision  1));
+}
+return C_PUBLIC;
+}
+}
+if (backup)
+return C_BACKUP;
+return C_PROTECTED;
+}
+
+
 
 
 // THREAD TESTER
@@ -128,7 +241,7 @@
   GCTID_STRUCT_NODE);
 }
 for (i = PREBUILT; i  PREBUILT + NUMROOTS; i++) {
-td.roots[i] = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE);
+td.roots[i] = (gcptr)allocate_node();
 }
 
 }
@@ -149,9 +262,6 @@
 
 k = get_rand(14);
 
-if (!p) // some parts expect it to be != 0
-p = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE);
-
 switch (k) {
 case 0: // remove a root
 if (num  0)
@@ -162,19 +272,21 @@
 p = _r;
 break;
 case 2: // add 'p' to roots
-if (td.num_roots  MAXROOTS)
+if (p  td.num_roots  MAXROOTS)
 td.roots[td.num_roots++] 

[pypy-commit] stmgc default: add more stm_normalize_stolen_objects where needed

2013-06-20 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r200:0efe1499373f
Date: 2013-06-20 09:30 +0200
http://bitbucket.org/pypy/stmgc/changeset/0efe1499373f/

Log:add more stm_normalize_stolen_objects where needed

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -698,8 +698,12 @@
   long long elapsed_time;
 
   /* acquire the lock, but don't double-acquire it if already committing */
-  if (d-public_descriptor-collection_lock != 'C')
+  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(d-active != 0);
   assert(!is_inevitable(d));
@@ -870,6 +874,8 @@
   revision_t my_lock = d-my_lock;
   wlog_t *item;
 
+  assert(d-public_descriptor-stolen_objects.size == 0);
+
   if (!g2l_any_entry(d-public_to_private))
 return;
 
@@ -1025,6 +1031,7 @@
   gcptr *items = d-private_from_protected.items;
   revision_t new_revision = cur_time + 1; // make an odd number
   assert(new_revision  1);
+  assert(d-public_descriptor-stolen_objects.size == 0);
 
   for (i = 0; i  size; i++)
 {
@@ -1125,7 +1132,6 @@
   spinlock_acquire(d-public_descriptor-collection_lock, 'C');  /*committing*/
   if (d-public_descriptor-stolen_objects.size != 0)
 stm_normalize_stolen_objects(d);
-
   AcquireLocks(d);
 
   if (is_inevitable(d))
@@ -1151,6 +1157,9 @@
   inev_mutex_acquire();   // wait until released
   inev_mutex_release();
   spinlock_acquire(d-public_descriptor-collection_lock, 'C');
+  if (d-public_descriptor-stolen_objects.size != 0)
+stm_normalize_stolen_objects(d);
+
   AcquireLocks(d);
   continue;
 }
@@ -1162,6 +1171,7 @@
 if (!ValidateDuringTransaction(d, 1))
   AbortTransaction(ABRT_VALIDATE_COMMIT);
 }
+
   CommitPrivateFromProtected(d, cur_time);
 
   /* we cannot abort any more from here */
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: doesn't crash

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r218:7ed5c33f287e
Date: 2013-06-20 21:09 +0200
http://bitbucket.org/pypy/stmgc/changeset/7ed5c33f287e/

Log:doesn't crash

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -59,7 +59,7 @@
 assert(tid == (tid  STM_USER_TID_MASK));
 P-h_tid = tid;
 P-h_revision = stm_private_rev_num;
-P-h_original = NULL;
+P-h_original = 0;
 return P;
 }
 
@@ -77,7 +77,7 @@
 if (P-h_original)
 L-h_original = P-h_original;
 else
-L-h_original = P;
+L-h_original = (revision_t)P;
 
 return L;
 }
@@ -93,7 +93,7 @@
 if (P-h_original)
 L-h_original = P-h_original;
 else
-L-h_original = P;
+L-h_original = (revision_t)P;
 
 return L;
 }
@@ -114,28 +114,21 @@
 
 //p-h_original == NULL
 if (!(p-h_tid  GCFLAG_OLD)) {//(is_in_nursery(p)) {
-// preallocate old original outside
+struct tx_descriptor *d = thread_descriptor;
+spinlock_acquire(d-public_descriptor-collection_lock, 'I');
+// preallocate old original outside;
 // like stealing
-gcptr O = stmgc_duplicate_old(L);
-L-h_revision = (revision_t)O;
-L-h_original = O;
-L-h_tid |= GCFLAG_HAS_ID;
+gcptr O = stmgc_duplicate_old(p);
+p-h_revision = (revision_t)O;
+p-h_original = (revision_t)O;
+p-h_tid |= GCFLAG_HAS_ID;
 
-
-// could be stolen
-if (p-h_tid  GCFLAG_NURSERY_MOVED) {
-
-}
-}
-else if (p-h_tid  GCFLAG_NURSERY_MOVED) {
-if (p-h_tid  GCFLAG_PUBLIC) {
-// moved by stealing
-
-}
-   
+spinlock_release(d-public_descriptor-collection_lock);
+return (revision_t)O;
 }
 else {
-assert(0);
+// p is the original itself
+return (revision_t)p;
 }
 }
 
@@ -161,7 +154,7 @@
 return fresh_old_copy;
 }
 
-static inline void copy_to_old_id_copy(gcptr obj, gcptr id)
+inline void copy_to_old_id_copy(gcptr obj, gcptr id)
 {
 size_t size = stmcb_size(obj);
 memcpy(id, obj, size);
@@ -191,7 +184,8 @@
 
 if (obj-h_tid  GCFLAG_HAS_ID) {
 /* already has a place to go to */
-fresh_old_copy = copy_to_old_id_copy(obj, obj-h_original);
+copy_to_old_id_copy(obj, (gcptr)obj-h_original);
+fresh_old_copy = (gcptr)obj-h_original;
 } 
 else {
 /* make a copy of it outside */
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -11,6 +11,8 @@
 struct stm_object_s stubs[STUB_NB_OBJS];
 };
 
+inline void copy_to_old_id_copy(gcptr obj, gcptr id);
+
 gcptr stm_stub_malloc(struct tx_public_descriptor *pd)
 {
 assert(pd-collection_lock != 0);
@@ -152,16 +154,16 @@
 if (!(L-h_tid  GCFLAG_OLD)) { 
 gcptr O;
 if (L-h_tid  GCFLAG_HAS_ID) {
+O = (gcptr)L-h_original;
 L-h_tid = ~GCFLAG_HAS_ID;
-L-h_revision = (revision_t)L-h_original;
-copy_to_old_id_copy(L, L-h_original);
-O = L-h_original;
+L-h_revision = (revision_t)O;
+copy_to_old_id_copy(L, (gcptr)L-h_original);
 } else {
 /* Copy the object out of the other thread's nursery, 
if needed */
 O = stmgc_duplicate_old(L);
 L-h_revision = (revision_t)O;
-L-h_original = O;
+L-h_original = (revision_t)O;
 }
 L-h_tid |= GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED;
 /* subtle: we need to remove L from the fxcache of the target
diff --git a/c4/steal.h b/c4/steal.h
--- a/c4/steal.h
+++ b/c4/steal.h
@@ -2,7 +2,7 @@
 #define _SRCSTM_STEAL_H
 
 
-#define STUB_BLOCK_SIZE   (16 * WORD)/* power of two */
+#define STUB_BLOCK_SIZE   (32 * WORD)/* power of two */
 
 #define STUB_THREAD(h)(*(struct tx_public_descriptor **)   \
 (((revision_t)(h))  ~(STUB_BLOCK_SIZE-1)))
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -10,7 +10,7 @@
 typedef struct stm_object_s {
 revision_t h_tid;
 revision_t h_revision;
-gcptr h_original;
+revision_t h_original;
 } *gcptr;
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: intermediate backup before rewrite

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r219:589d41f3af88
Date: 2013-06-21 11:50 +0200
http://bitbucket.org/pypy/stmgc/changeset/589d41f3af88/

Log:intermediate backup before rewrite

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -27,6 +27,7 @@
 struct node {
 struct stm_object_s hdr;
 long value;
+revision_t id;
 struct node *next;
 };
 typedef struct node * nodeptr;
@@ -82,6 +83,7 @@
 gcptr x = calloc(1, size);
 x-h_tid = PREBUILT_FLAGS | tid;
 x-h_revision = PREBUILT_REVISION;
+x-h_original = 0;
 return x;
 }
 
@@ -260,7 +262,7 @@
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
 
-k = get_rand(15);
+k = get_rand(16);
 
 switch (k) {
 case 0: // remove a root
@@ -322,6 +324,17 @@
 pop_roots();
 p = NULL;
 break;
+case 15:
+w_r = (nodeptr)read_barrier(_r);
+if (w_r-id) {
+assert(w_r-id == stm_id((gcptr)w_r));
+assert(w_r-id == stm_id((gcptr)_r));
+} 
+else {
+w_r = (nodeptr)write_barrier(_r);
+w_r-id = stm_id((gcptr)w_r);
+assert(w_r-id == stm_id((gcptr)_r));
+}
 }
 return p;
 }
@@ -348,8 +361,8 @@
 int interruptible_callback(gcptr arg1, int retry_counter)
 {
 td.num_roots = td.num_roots_outside_perform;
-// done by the following pop_roots():
-//copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
+// done  overwritten by the following pop_roots():
+// copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
 
 // refresh td.roots:
 arg1 = stm_pop_root();
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -446,7 +446,9 @@
 
   B = stmgc_duplicate_old(P);
   B-h_tid |= GCFLAG_BACKUP_COPY;
-
+  if (P-h_tid  GCFLAG_OLD)
+B-h_original = P;
+  
   P-h_tid |= GCFLAG_PRIVATE_FROM_PROTECTED;
   P-h_revision = (revision_t)B;
 
@@ -473,6 +475,9 @@
   /* note that stmgc_duplicate() usually returns a young object, but may
  return an old one if the nursery is full at this moment. */
   gcptr L = stmgc_duplicate(R);
+  if (!(L-h_original))
+L-h_original = (revision_t)R;
+
   assert(!(L-h_tid  GCFLAG_BACKUP_COPY));
   assert(!(L-h_tid  GCFLAG_STUB));
   assert(!(L-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
@@ -1003,7 +1008,12 @@
   stub-h_tid = (L-h_tid  STM_USER_TID_MASK) | GCFLAG_PUBLIC
| GCFLAG_STUB
| GCFLAG_OLD;
+  assert(!(L-h_tid  GCFLAG_HAS_ID));
   stub-h_revision = ((revision_t)L) | 2;
+  if (L-h_original)
+stub-h_original = L-h_original;
+  else
+L-h_original = (revision_t)stub;
   item-val = stub;
 
 } G2L_LOOP_END;
@@ -1069,6 +1079,8 @@
 
   if (B-h_tid  GCFLAG_PUBLIC)
 {
+  assert(!(P-h_tid  GCFLAG_HAS_ID));
+
   /* B was stolen */
   while (1)
 {
@@ -1080,6 +1092,13 @@
 break;
 }
 }
+  else if (P-h_tid  GCFLAG_HAS_ID) {
+/* The backup is the id object.  */
+B-h_tid = ~GCFLAG_BACKUP_COPY;
+B-h_tid |= GCFLAG_PUBLIC;
+P-h_tid = ~GCFLAG_HAS_ID;
+B-h_revision = (revision_t)P;
+  }
   else
 {
   stmgcpage_free(B);
@@ -,6 +1130,7 @@
 {
   assert(!(B-h_tid  GCFLAG_BACKUP_COPY));
   P-h_tid |= GCFLAG_PUBLIC;
+  P-h_tid = ~GCFLAG_HAS_ID; // just in case
   if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
   /* P becomes a public outdated object.  It may create an
  exception documented in doc-objects.txt: a public but young
@@ -1119,10 +1139,20 @@
  stealing will follow its h_revision (to B).
   */
 }
+  else if (P-h_tid  GCFLAG_HAS_ID) {
+/* The backup is the id object.  P becomes outdated. */
+P-h_tid |= GCFLAG_PUBLIC;
+P-h_tid = ~GCFLAG_HAS_ID;
+B-h_tid |= GCFLAG_PUBLIC;
+B-h_tid = ~GCFLAG_BACKUP_COPY;
+if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
+fprintf(stderr, %p made outdated, %p is current\n, P, B);
+  }
   else
 {
   /* copy the backup copy B back over the now-protected object P,
  and then free B, which will not be used any more. */
+  assert(B-h_original == P);
   size_t size = stmcb_size(B);
   assert(B-h_tid  GCFLAG_BACKUP_COPY);
   memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -74,11 +74,6 @@
 L-h_tid = ~GCFLAG_OLD;
 L-h_tid = ~GCFLAG_HAS_ID;
 
-if (P-h_original)
-L-h_original = P-h_original;
-else
-L-h_original = (revision_t)P;
-
 return L;
 }
 
@@ -88,12 +83,7 @@
 gcptr 

[pypy-commit] stmgc implement-id: merge default

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r222:2fe2cb9597de
Date: 2013-06-21 13:25 +0200
http://bitbucket.org/pypy/stmgc/changeset/2fe2cb9597de/

Log:merge default

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -199,6 +199,7 @@
 }
 
   fprintf(stderr, readobj: %p\n, P);
+  assert(!(P-h_tid  GCFLAG_STUB));
   gcptrlist_insert(d-list_of_read_objects, P);
 
  add_in_recent_reads_cache:
@@ -492,6 +493,8 @@
 GCFLAG_WRITE_BARRIER |
 0);
   L-h_revision = stm_private_rev_num;
+  assert(stm_private_rev_num  0);
+  assert(stm_private_rev_num  1);
   g2l_insert(d-public_to_private, R, L);
   fprintf(stderr, write_barrier: adding %p - %p to public_to_private\n,
   R, L);
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -195,8 +195,11 @@
 return;
 
  restart:
-if (obj-h_tid  GCFLAG_VISITED)
+if (obj-h_tid  GCFLAG_VISITED) {
+fprintf(stderr, [already visited: %p]\n, obj);
+assert(obj == *pobj);
 return;/* already seen */
+}
 
 if (obj-h_revision  1) {
 assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
@@ -223,7 +226,8 @@
 assert(*pobj == prev_obj);
 gcptr obj1 = obj;
 visit(obj1);   /* recursion, but should be only once */
-prev_obj-h_revision = ((revision_t)obj1) + 2;
+assert(prev_obj-h_tid  GCFLAG_STUB);
+prev_obj-h_revision = ((revision_t)obj1) | 2;
 return;
 }
 }
@@ -245,8 +249,11 @@
 B-h_tid |= GCFLAG_VISITED;
 }
 else {
+/* a private_from_protected with a stolen backup copy B */
 assert(!(B-h_tid  GCFLAG_BACKUP_COPY));
-abort();  // XXX
+gcptr obj1 = B;
+visit(obj1); /* xxx recursion? */
+obj-h_revision = (revision_t)obj1;
 }
 }
 obj-h_tid |= GCFLAG_VISITED;
@@ -286,8 +293,12 @@
 {
 //assert(*root == END_MARKER);
 //root++;
-while (root != end)
-visit(root++);
+while (root != end) {
+gcptr o = *root;
+visit(root);
+fprintf(stderr, visit stack root: %p - %p\n, o, *root);
+root++;
+}
 }
 
 static void mark_all_stack_roots(void)
@@ -346,14 +357,20 @@
 
 for (i = d-list_of_read_objects.size - 1; i = 0; --i) {
 gcptr obj = items[i];
+assert(!(obj-h_tid  GCFLAG_STUB));
 
 /* Warning: in case the object listed is outdated and has been
replaced with a more recent revision, then it might be the
case that obj-h_revision doesn't have GCFLAG_VISITED, but
just removing it is very wrong --- we want 'd' to abort.
 */
+if (obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
+assert(IS_POINTER(obj-h_revision));
+obj = (gcptr)obj-h_revision;
+}
+
 revision_t v = obj-h_revision;
-if (IS_POINTER(v)  !(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED)) {
+if (IS_POINTER(v)) {
 /* has a more recent revision.  Oups. */
 fprintf(stderr,
 ABRT_COLLECT_MAJOR: %p was read but modified already\n,
@@ -528,6 +545,7 @@
 struct tx_descriptor *d;
 struct tx_descriptor *saved = thread_descriptor;
 revision_t saved_private_rev = stm_private_rev_num;
+char *read_barrier_cache = stm_read_barrier_cache;
 assert(saved_private_rev == *saved-private_revision_ref);
 
 for (d = stm_tx_head; d; d = d-tx_next) {
@@ -536,16 +554,19 @@
collection was not preceeded by a minor collection if the
thread is busy in a system call for example.
 */
-if (stmgc_minor_collect_anything_to_do(d)) {
+if (stmgc_minor_collect_anything_to_do(d) ||
+(d-public_descriptor-stolen_objects.size != 0)) {
 /* Hack: temporarily pretend that we are the other thread...
  */
 thread_descriptor = d;
 stm_private_rev_num = *d-private_revision_ref;
+fxcache_install(d-recent_reads_cache);
 //assert(stmgc_nursery_hiding(d, 0));
 stmgc_minor_collect_no_abort();
 //assert(stmgc_nursery_hiding(d, 1));
 thread_descriptor = saved;
 stm_private_rev_num = saved_private_rev;
+stm_read_barrier_cache = read_barrier_cache;
 }
 }
 }
@@ -582,7 +603,7 @@
 countdown_next_major_coll = next;
 }
 
-void stm_major_collect(void)
+static void major_collect(void)
 {
 stmgcpage_acquire_global_lock();
 fprintf(stderr, ,-\n| running major collection...\n);
@@ -628,7 +649,7 @@
threads will also acquire the RW lock in exclusive mode, but won't
do anything. */
 if (countdown_next_major_coll == 0)
-stm_major_collect();
+major_collect();
 
 stm_stop_single_thread();
 
diff --git 

[pypy-commit] stmgc implement-id: minor changes

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r221:16af90468dcd
Date: 2013-06-21 13:23 +0200
http://bitbucket.org/pypy/stmgc/changeset/16af90468dcd/

Log:minor changes

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -446,6 +446,7 @@
 
   B = stmgc_duplicate_old(P);
   B-h_tid |= GCFLAG_BACKUP_COPY;
+  B-h_tid = ~GCFLAG_HAS_ID;
   if (!(P-h_original)  (P-h_tid  GCFLAG_OLD)) {
   B-h_original = (revision_t)P;
   }
@@ -1021,6 +1022,7 @@
   }
   else {
 L-h_original = (revision_t)stub;
+assert(0);
   }
   
   item-val = stub;
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -83,7 +83,6 @@
 gcptr L = (gcptr)stmgcpage_malloc(size);
 memcpy(L, P, size);
 L-h_tid |= GCFLAG_OLD;
-assert(!(L-h_tid  GCFLAG_HAS_ID));
 
 return L;
 }
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -89,6 +89,7 @@
 }
 else {
 obj-h_original = (revision_t)stub;
+assert(0);
 }
 
 g2l_insert(sd-all_stubs, obj, stub);
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: merge

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r217:74a48c97a3f6
Date: 2013-06-20 16:53 +0200
http://bitbucket.org/pypy/stmgc/changeset/74a48c97a3f6/

Log:merge

diff --git a/c4/demo2.c b/c4/demo2.c
--- a/c4/demo2.c
+++ b/c4/demo2.c
@@ -105,7 +105,7 @@
  stm_read_barrier((gcptr)r_next))) {
 asm volatile (pause:::memory);  /* smp_spinloop() */
 i++;
-assert(i  1000);
+assert(i  100);
 }
 // for now:
 assert(((nodeptr)stm_read_barrier((gcptr)r_prev-next))-value 
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -972,7 +972,7 @@
 } G2L_LOOP_END;
 }
 
-//static pthread_mutex_t mutex_prebuilt_gcroots = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_prebuilt_gcroots = PTHREAD_MUTEX_INITIALIZER;
 
 static void UpdateChainHeads(struct tx_descriptor *d, revision_t cur_time,
  revision_t localrev)
@@ -1028,16 +1028,13 @@
 #endif
   ACCESS_ONCE(R-h_revision) = v;
 
-#if 0
   if (R-h_tid  GCFLAG_PREBUILT_ORIGINAL)
 {
   /* cannot possibly get here more than once for a given value of R */
   pthread_mutex_lock(mutex_prebuilt_gcroots);
   gcptrlist_insert(stm_prebuilt_gcroots, R);
   pthread_mutex_unlock(mutex_prebuilt_gcroots);
-  /*mark*/
 }
-#endif
 
 } G2L_LOOP_END;
 
@@ -1433,6 +1430,8 @@
   /* we are reusing 'pd' */
   descriptor_array_free_list = pd-free_list_next;
   assert(descriptor_array_free_list = 0);
+  assert(pd-stolen_objects.size == 0);
+  assert(pd-stolen_young_stubs.size == 0);
   assert(pd-collection_lock == 0 || pd-collection_lock == -1);
   pd-collection_lock = 0;
   }
@@ -1483,8 +1482,12 @@
 assert(d-active == 0);
 stmgcpage_acquire_global_lock();
 
-/* our nursery is empty at this point */
+/* our nursery is empty at this point.  The list 'stolen_objects'
+   should have been emptied at the previous minor collection and
+   should remain empty because we don't have any young object. */
+assert(d-public_descriptor-stolen_objects.size == 0);
 assert(d-public_descriptor-stolen_young_stubs.size == 0);
+gcptrlist_delete(d-public_descriptor-stolen_objects);
 gcptrlist_delete(d-public_descriptor-stolen_young_stubs);
 
 stmgcpage_done_tls();
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -199,21 +199,56 @@
 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() */
 }
-else {
+else if (obj-h_tid  GCFLAG_PUBLIC) {
 /* h_revision is a ptr: we have a more recent version */
-assert(!(obj-h_tid  GCFLAG_STUB));
 gcptr prev_obj = obj;
-obj = (gcptr)obj-h_revision;   /* go visit the more recent version */
 
-if (!(obj-h_tid  GCFLAG_VISITED)  IS_POINTER(obj-h_revision)) {
+if (!(obj-h_revision  2)) {
+/* go visit the more recent version */
 obj = (gcptr)obj-h_revision;
+}
+else {
+/* it's a stub: keep it if it points to a protected version,
+   because we need to keep the effect of stealing if it is
+   later accessed by the wrong thread.  If it points to a
+   public object (possibly outdated), we can ignore the stub.
+*/
+assert(obj-h_tid  GCFLAG_STUB);
+obj = (gcptr)(obj-h_revision - 2);
+if (!(obj-h_tid  GCFLAG_PUBLIC)) {
+prev_obj-h_tid |= GCFLAG_VISITED;
+assert(*pobj == prev_obj);
+gcptr obj1 = obj;
+visit(obj1);   /* recursion, but should be only once */
+prev_obj-h_revision = ((revision_t)obj1) + 2;
+return;
+}
+}
+
+if (!(obj-h_revision  3)) {
+obj = (gcptr)obj-h_revision;
+assert(obj-h_tid  GCFLAG_PUBLIC);
 prev_obj-h_revision = (revision_t)obj;
 }
 *pobj = obj;
 goto restart;
 }
+else {
+assert(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED);
+gcptr B = (gcptr)obj-h_revision;
+if (!(B-h_tid  GCFLAG_PUBLIC)) {
+/* a regular private_from_protected object with a backup copy B */
+assert(B-h_tid  GCFLAG_BACKUP_COPY);
+B-h_tid |= GCFLAG_VISITED;
+}
+else {
+assert(!(B-h_tid  GCFLAG_BACKUP_COPY));
+abort();  // XXX
+}
+}
 obj-h_tid |= GCFLAG_VISITED;
 gcptrlist_insert(objects_to_trace, obj);
 }
@@ -304,6 +339,11 @@
 if (d-active  0)
 return;   /* already aborted during forced minor collection */
 
+if (d-active == 2) {
+/* inevitable transaction: clear the 

[pypy-commit] stmgc default: minor changes

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r215:a295fa0455e1
Date: 2013-06-20 14:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/a295fa0455e1/

Log:minor changes

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -183,12 +183,12 @@
 return result1;
 }
 
-static const revision_t C_PRIVATE_FROM_PROTECTED = 1;
-static const revision_t C_PRIVATE= 2;
-static const revision_t C_STUB   = 3;
-static const revision_t C_PUBLIC = 4;
-static const revision_t C_BACKUP = 5;
-static const revision_t C_PROTECTED  = 6;
+static const int C_PRIVATE_FROM_PROTECTED = 1;
+static const int C_PRIVATE= 2;
+static const int C_STUB   = 3;
+static const int C_PUBLIC = 4;
+static const int C_BACKUP = 5;
+static const int C_PROTECTED  = 6;
 int classify(gcptr p)
 {
 int priv_from_prot = (p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) != 0;
@@ -260,7 +260,7 @@
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
 
-k = get_rand(14);
+k = get_rand(15);
 
 switch (k) {
 case 0: // remove a root
@@ -316,7 +316,11 @@
 w_sr = (nodeptr)write_barrier(_sr);
 w_sr-next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)];
 break;
-default:
+case 14:
+push_roots();
+stmgc_minor_collect();
+pop_roots();
+p = NULL;
 break;
 }
 return p;
@@ -344,17 +348,21 @@
 int interruptible_callback(gcptr arg1, int retry_counter)
 {
 td.num_roots = td.num_roots_outside_perform;
-copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
+// done by the following pop_roots():
+//copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
 
+// refresh td.roots:
 arg1 = stm_pop_root();
+assert(arg1 == NULL);
 pop_roots();
 push_roots();
 stm_push_root(arg1);
 
 int p = run_me();
-int restart = p == -1 ? get_rand(3) != 1 : 0;
+if (p == -1) // maybe restart transaction
+return get_rand(3) != 1;
 
-return restart;
+return 0;
 }
 
 int run_me()
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: amazingly seems to not crash..

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r220:c0ff042ed265
Date: 2013-06-21 13:08 +0200
http://bitbucket.org/pypy/stmgc/changeset/c0ff042ed265/

Log:amazingly seems to not crash..

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -446,8 +446,9 @@
 
   B = stmgc_duplicate_old(P);
   B-h_tid |= GCFLAG_BACKUP_COPY;
-  if (P-h_tid  GCFLAG_OLD)
-B-h_original = P;
+  if (!(P-h_original)  (P-h_tid  GCFLAG_OLD)) {
+  B-h_original = (revision_t)P;
+  }
   
   P-h_tid |= GCFLAG_PRIVATE_FROM_PROTECTED;
   P-h_revision = (revision_t)B;
@@ -475,8 +476,10 @@
   /* note that stmgc_duplicate() usually returns a young object, but may
  return an old one if the nursery is full at this moment. */
   gcptr L = stmgc_duplicate(R);
-  if (!(L-h_original))
+  if (!(L-h_original)) {
+assert(R-h_tid  GCFLAG_OLD); // if not, force stm_id??
 L-h_original = (revision_t)R;
+  }
 
   assert(!(L-h_tid  GCFLAG_BACKUP_COPY));
   assert(!(L-h_tid  GCFLAG_STUB));
@@ -1010,10 +1013,16 @@
| GCFLAG_OLD;
   assert(!(L-h_tid  GCFLAG_HAS_ID));
   stub-h_revision = ((revision_t)L) | 2;
-  if (L-h_original)
+  if (L-h_original) {
 stub-h_original = L-h_original;
-  else
+  }
+  else if (L-h_tid  GCFLAG_OLD) {
+stub-h_original = (revision_t)L;
+  }
+  else {
 L-h_original = (revision_t)stub;
+  }
+  
   item-val = stub;
 
 } G2L_LOOP_END;
@@ -1091,12 +1100,13 @@
   if (bool_cas(B-h_revision, v, (revision_t)P))
 break;
 }
-}
-  else if (P-h_tid  GCFLAG_HAS_ID) {
-/* The backup is the id object.  */
+}  
+  else if (P-h_original == (revision_t)B) {
+/* The backup is the id object */
+assert(!(P-h_tid  GCFLAG_HAS_ID));
+
 B-h_tid = ~GCFLAG_BACKUP_COPY;
 B-h_tid |= GCFLAG_PUBLIC;
-P-h_tid = ~GCFLAG_HAS_ID;
 B-h_revision = (revision_t)P;
   }
   else
@@ -1139,10 +1149,10 @@
  stealing will follow its h_revision (to B).
   */
 }
-  else if (P-h_tid  GCFLAG_HAS_ID) {
+  else if (P-h_original == (revision_t)B) {
 /* The backup is the id object.  P becomes outdated. */
+assert(!(P-h_tid  GCFLAG_HAS_ID));
 P-h_tid |= GCFLAG_PUBLIC;
-P-h_tid = ~GCFLAG_HAS_ID;
 B-h_tid |= GCFLAG_PUBLIC;
 B-h_tid = ~GCFLAG_BACKUP_COPY;
 if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
@@ -1152,7 +1162,8 @@
 {
   /* copy the backup copy B back over the now-protected object P,
  and then free B, which will not be used any more. */
-  assert(B-h_original == P);
+  assert(!(P-h_original) 
+ || (B-h_original == (revision_t)P-h_original));
   size_t size = stmcb_size(B);
   assert(B-h_tid  GCFLAG_BACKUP_COPY);
   memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -101,93 +101,51 @@
 struct tx_descriptor *d = thread_descriptor;
 revision_t result;
 
+spinlock_acquire(d-public_descriptor-collection_lock, 'I');
 if (p-h_original) {
-fprintf(stderr, stm_id(%p) has original: %p\n, p, 
(gcptr)p-h_original);
+spinlock_release(d-public_descriptor-collection_lock);
 return p-h_original;
 }
 
-spinlock_acquire(d-public_descriptor-collection_lock, 'I');
+/* old objects must have an h_original OR be
+   the original itself. 
+   if some thread stole p when it was still young,
+   it must have set h_original. stealing an old obj
+   makes the old obj original.
+*/
 if (p-h_tid  GCFLAG_OLD) {
 /* it must be this exact object */
 result = (revision_t)p;
 }
 else {
-/* must create shadow original object */
-gcptr O = stmgc_duplicate_old(p);
-p-h_original = (revision_t)O;
-p-h_tid |= GCFLAG_HAS_ID;
-O-h_tid |= GCFLAG_PUBLIC;
-
-result = (revision_t)O;
-
-fprintf(stderr, stm_id(%p): is young, preallocate old id-copy %p\n,
-p, O);
-}
-
-
-if (p-h_original) {
-// maybe in the meantime?
-fprintf(stderr, stm_id(%p) has original NOW: %p\n, p, 
(gcptr)p-h_original);
-spinlock_release(d-public_descriptor-collection_lock);
-return p-h_original;
-}
-
-//p-h_original == NULL
-
-if (p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
-gcptr B = (gcptr)p-h_revision;
-if (p-h_tid  GCFLAG_OLD) {
-/* may have become old after becoming priv_from_prot */
-if (B-h_tid  GCFLAG_BACKUP_COPY) {
-B-h_original = p;
-result = (revision_t)p;
-fprintf(stderr, stm_id(%p): is priv_from_prot and old. make 
);
-  

[pypy-commit] stmgc implement-id: work in progress

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r216:04f0776e142a
Date: 2013-06-20 16:51 +0200
http://bitbucket.org/pypy/stmgc/changeset/04f0776e142a/

Log:work in progress

diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -57,6 +57,9 @@
  * but converted from a protected.  These are precisely the objects
  * that have a backup copy (in h_revision), which gives a copy of the
  * original protected object.
+ * 
+ * GCFLAG_HAS_ID is set on young objects that have an old reserved
+ * memory to be copied to in minor collections (obj-h_original)
  */
 static const revision_t GCFLAG_OLD= STM_FIRST_GCFLAG  0;
 static const revision_t GCFLAG_VISITED= STM_FIRST_GCFLAG  1;
@@ -68,6 +71,7 @@
 static const revision_t GCFLAG_BACKUP_COPY  /*debug*/ = STM_FIRST_GCFLAG  7;
 static const revision_t GCFLAG_STUB /*debug*/ = STM_FIRST_GCFLAG  8;
 static const revision_t GCFLAG_PRIVATE_FROM_PROTECTED = STM_FIRST_GCFLAG  9;
+static const revision_t GCFLAG_HAS_ID = STM_FIRST_GCFLAG  10;
 
 /* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
 #define GCFLAG_PREBUILT  (GCFLAG_VISITED   | \
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -59,6 +59,7 @@
 assert(tid == (tid  STM_USER_TID_MASK));
 P-h_tid = tid;
 P-h_revision = stm_private_rev_num;
+P-h_original = NULL;
 return P;
 }
 
@@ -71,6 +72,13 @@
 
 memcpy(L, P, size);
 L-h_tid = ~GCFLAG_OLD;
+L-h_tid = ~GCFLAG_HAS_ID;
+
+if (P-h_original)
+L-h_original = P-h_original;
+else
+L-h_original = P;
+
 return L;
 }
 
@@ -80,11 +88,64 @@
 gcptr L = (gcptr)stmgcpage_malloc(size);
 memcpy(L, P, size);
 L-h_tid |= GCFLAG_OLD;
+L-h_tid = ~GCFLAG_HAS_ID;
+
+if (P-h_original)
+L-h_original = P-h_original;
+else
+L-h_original = P;
+
 return L;
 }
 
 //
 
+
+revision_t stm_hash(gcptr p)
+{
+return stm_id(p);
+}
+
+revision_t stm_id(gcptr p)
+{
+if (p-h_original) {
+return p-h_original;
+}
+
+//p-h_original == NULL
+if (!(p-h_tid  GCFLAG_OLD)) {//(is_in_nursery(p)) {
+// preallocate old original outside
+// like stealing
+gcptr O = stmgc_duplicate_old(L);
+L-h_revision = (revision_t)O;
+L-h_original = O;
+L-h_tid |= GCFLAG_HAS_ID;
+
+
+// could be stolen
+if (p-h_tid  GCFLAG_NURSERY_MOVED) {
+
+}
+}
+else if (p-h_tid  GCFLAG_NURSERY_MOVED) {
+if (p-h_tid  GCFLAG_PUBLIC) {
+// moved by stealing
+
+}
+   
+}
+else {
+assert(0);
+}
+}
+
+revision_t stm_pointer_equal(gcptr p1, gcptr p2)
+{
+return stm_id(p1) == stm_id(p2);
+}
+
+//
+
 static inline gcptr create_old_object_copy(gcptr obj)
 {
 assert(!(obj-h_tid  GCFLAG_PUBLIC));
@@ -100,6 +161,13 @@
 return fresh_old_copy;
 }
 
+static inline void copy_to_old_id_copy(gcptr obj, gcptr id)
+{
+size_t size = stmcb_size(obj);
+memcpy(id, obj, size);
+id-h_tid = ~GCFLAG_HAS_ID;
+}
+
 static void visit_if_young(gcptr *root)
 {
 gcptr obj = *root;
@@ -111,17 +179,25 @@
 }
 else {
 /* it's a nursery object.  Was it already moved? */
-
 if (UNLIKELY(obj-h_tid  GCFLAG_NURSERY_MOVED)) {
 /* yes.  Such an object can be a public object in the nursery
too (such objects are always NURSERY_MOVED).  For all cases,
-   we can just fix the ref. */
+   we can just fix the ref. 
+   Can be stolen objects or those we already moved.
+*/
 *root = (gcptr)obj-h_revision;
 return;
 }
 
-/* make a copy of it outside */
-fresh_old_copy = create_old_object_copy(obj);
+if (obj-h_tid  GCFLAG_HAS_ID) {
+/* already has a place to go to */
+fresh_old_copy = copy_to_old_id_copy(obj, obj-h_original);
+} 
+else {
+/* make a copy of it outside */
+fresh_old_copy = create_old_object_copy(obj);
+}
+
 obj-h_tid |= GCFLAG_NURSERY_MOVED;
 obj-h_revision = (revision_t)fresh_old_copy;
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -149,10 +149,20 @@
 
 fprintf(stderr, stolen: %p - %p\n, P, L);
 
-/* Copy the object out of the other thread's nursery, if needed */
-if (!(L-h_tid  GCFLAG_OLD)) {
-gcptr O = stmgc_duplicate_old(L);
-L-h_revision = (revision_t)O;
+if (!(L-h_tid  GCFLAG_OLD)) { 
+gcptr O;
+if (L-h_tid  GCFLAG_HAS_ID) {
+L-h_tid = ~GCFLAG_HAS_ID;
+L-h_revision = (revision_t)L-h_original;
+  

[pypy-commit] stmgc implement-id: mark some paths with assert(0) because they don't seem to be reached in demo_random.c

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r225:08871aa2ccfe
Date: 2013-06-21 14:11 +0200
http://bitbucket.org/pypy/stmgc/changeset/08871aa2ccfe/

Log:mark some paths with assert(0) because they don't seem to be reached
in demo_random.c

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -449,7 +449,11 @@
   B-h_tid |= GCFLAG_BACKUP_COPY;
   B-h_tid = ~GCFLAG_HAS_ID;
   if (!(P-h_original)  (P-h_tid  GCFLAG_OLD)) {
-  B-h_original = (revision_t)P;
+/* if P is old, it must be the original
+   if P is young, it will create a shadow original later
+   or it's getting decided when backup gets stolen.
+*/
+B-h_original = (revision_t)P;
   }
   
   P-h_tid |= GCFLAG_PRIVATE_FROM_PROTECTED;
@@ -479,6 +483,8 @@
  return an old one if the nursery is full at this moment. */
   gcptr L = stmgc_duplicate(R);
   if (!(L-h_original)) {
+/* if we don't have an original object yet,
+ it must be the old public R */
 assert(R-h_tid  GCFLAG_OLD); // if not, force stm_id??
 L-h_original = (revision_t)R;
   }
@@ -1161,7 +1167,6 @@
 B-h_tid |= GCFLAG_PUBLIC;
 B-h_tid = ~GCFLAG_BACKUP_COPY;
 if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
-fprintf(stderr, %p made outdated, %p is current\n, P, B);
   }
   else
 {
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -100,12 +100,15 @@
 struct tx_descriptor *d = thread_descriptor;
 revision_t result;
 
+if (p-h_original) { /* fast path */
+return p-h_original;
+}
+
 spinlock_acquire(d-public_descriptor-collection_lock, 'I');
-if (p-h_original) {
+if (p-h_original) { /* maybe now? */
 spinlock_release(d-public_descriptor-collection_lock);
 return p-h_original;
 }
-
 /* old objects must have an h_original OR be
the original itself. 
if some thread stole p when it was still young,
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -84,9 +84,11 @@
 stub-h_revision = ((revision_t)obj) | 2;
 if (obj-h_original) {
 stub-h_original = obj-h_original;
+assert(0);
 }
 else if (obj-h_tid  GCFLAG_OLD) {
 stub-h_original = (revision_t)obj;
+assert(0);
 }
 else {
 obj-h_original = (revision_t)stub;
@@ -122,17 +124,21 @@
 gcptr B = (gcptr)L-h_revision; /* the backup copy */
 
 if (L-h_original) {
-/* may have HAS_ID */
+/* L has an original, may be GCFLAG_HAS_ID */
 B-h_original = L-h_original;
 }
 else if (L-h_tid  GCFLAG_OLD) {
+/* If old, it must be the original */
 assert(!(L-h_tid  GCFLAG_HAS_ID));
 /* original must be L */
 B-h_original = (revision_t)L;
+assert(0);
 }
 else {
-/* we can make the backup the original */
+/* we can make the backup the original
+ since L hasn't decided yet */
 L-h_original = (revision_t)B;
+assert(0);
 }
 
 /* B is now a backup copy, i.e. a protected object, and we own
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: close anonymous

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r224:348eb80ca0c9
Date: 2013-06-21 13:37 +0200
http://bitbucket.org/pypy/stmgc/changeset/348eb80ca0c9/

Log:close anonymous

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


[pypy-commit] stmgc implement-id: fix tests and remove some of the assert(0), as they at least seem to be hit in tests

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r226:98c1eebad13c
Date: 2013-06-21 14:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/98c1eebad13c/

Log:fix tests and remove some of the assert(0), as they at least seem to
be hit in tests

diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -84,15 +84,12 @@
 stub-h_revision = ((revision_t)obj) | 2;
 if (obj-h_original) {
 stub-h_original = obj-h_original;
-assert(0);
 }
 else if (obj-h_tid  GCFLAG_OLD) {
 stub-h_original = (revision_t)obj;
-assert(0);
 }
 else {
 obj-h_original = (revision_t)stub;
-assert(0);
 }
 
 g2l_insert(sd-all_stubs, obj, stub);
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -32,6 +32,7 @@
 typedef struct stm_object_s {
 revision_t h_tid;
 revision_t h_revision;
+revision_t h_original;
 } *gcptr;
 
 int gettid(gcptr);
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -12,7 +12,7 @@
 
 def test_HDR():
 import struct
-assert HDR == struct.calcsize(PP)
+assert HDR == struct.calcsize(PPP)
 
 def test_malloc_simple():
 assert count_pages() == 0
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: fix issue when HAS_ID flag gets removed

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r227:17d1d1ba2d0d
Date: 2013-06-21 15:11 +0200
http://bitbucket.org/pypy/stmgc/changeset/17d1d1ba2d0d/

Log:fix issue when HAS_ID flag gets removed
* updated demo_random

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -262,7 +262,7 @@
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
 
-k = get_rand(16);
+k = get_rand(17);
 
 switch (k) {
 case 0: // remove a root
@@ -324,7 +324,7 @@
 pop_roots();
 p = NULL;
 break;
-case 15:
+case 15: /* test stm_id on non-shared roots */
 w_r = (nodeptr)read_barrier(_r);
 if (w_r-id) {
 assert(w_r-id == stm_id((gcptr)w_r));
@@ -335,6 +335,17 @@
 w_r-id = stm_id((gcptr)w_r);
 assert(w_r-id == stm_id((gcptr)_r));
 }
+case 16: /* test stm_id on shared roots */
+w_sr = (nodeptr)read_barrier(_sr);
+if (w_sr-id) {
+assert(w_sr-id == stm_id((gcptr)w_sr));
+assert(w_sr-id == stm_id((gcptr)_sr));
+} 
+else {
+w_sr = (nodeptr)write_barrier(_sr);
+w_sr-id = stm_id((gcptr)w_sr);
+assert(w_sr-id == stm_id((gcptr)_sr));
+}
 }
 return p;
 }
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -100,24 +100,34 @@
 struct tx_descriptor *d = thread_descriptor;
 revision_t result;
 
+
 if (p-h_original) { /* fast path */
+fprintf(stderr, stm_id(%p) has orig fst: %p\n, p, p-h_original);
 return p-h_original;
+} 
+else if (!(p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED)
+(p-h_tid  GCFLAG_OLD)) {
+/* we can be sure that p-h_original doesn't
+   get set during the if and the else-if */
+fprintf(stderr, stm_id(%p) is old, orig=0 fst: %p\n, p, p);
+return (revision_t)p;
 }
 
 spinlock_acquire(d-public_descriptor-collection_lock, 'I');
-if (p-h_original) { /* maybe now? */
-spinlock_release(d-public_descriptor-collection_lock);
-return p-h_original;
-}
-/* old objects must have an h_original OR be
+/* old objects must have an h_original xOR be
the original itself. 
if some thread stole p when it was still young,
it must have set h_original. stealing an old obj
makes the old obj original.
 */
-if (p-h_tid  GCFLAG_OLD) {
+if (p-h_original) { /* maybe now? */
+result = p-h_original;
+fprintf(stderr, stm_id(%p) has orig: %p\n, p, p-h_original);
+}
+else if (p-h_tid  GCFLAG_OLD) {
 /* it must be this exact object */
 result = (revision_t)p;
+fprintf(stderr, stm_id(%p) is old, orig=0: %p\n, p, p);
 }
 else {
 /* must create shadow original object or use
@@ -130,6 +140,8 @@
 // B-h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
 
 result = (revision_t)B;
+fprintf(stderr, stm_id(%p) young, pfp, use backup %p\n, 
+p, p-h_original);
 }
 else {
 gcptr O = stmgc_duplicate_old(p);
@@ -138,6 +150,7 @@
 O-h_tid |= GCFLAG_PUBLIC;
 
 result = (revision_t)O;
+fprintf(stderr, stm_id(%p) young, make shadow %p\n, p, O); 
 }
 }
 
@@ -147,7 +160,9 @@
 
 revision_t stm_pointer_equal(gcptr p1, gcptr p2)
 {
-/* XXX: */
+/* types must be the same */
+if ((p1-h_tid  STM_USER_TID_MASK) != (p2-h_tid  STM_USER_TID_MASK))
+return 0;
 return stm_id(p1) == stm_id(p2);
 }
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -195,7 +195,11 @@
if needed */
 O = stmgc_duplicate_old(L);
 L-h_revision = (revision_t)O;
-L-h_original = (revision_t)O;
+
+/* young and without original?
+   we may lose the HAS_ID flag like above */
+if (!(L-h_original))
+L-h_original = (revision_t)O;
 }
 
 L-h_tid |= GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED;
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc implement-id: add simple tests

2013-06-21 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: implement-id
Changeset: r228:d8b5144c17f4
Date: 2013-06-21 16:46 +0200
http://bitbucket.org/pypy/stmgc/changeset/d8b5144c17f4/

Log:add simple tests

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -13,7 +13,7 @@
 
 
 #define NUMTHREADS 4
-#define STEPS 10
+#define STEPS 100
 #define NUMROOTS 10 // per thread
 #define PREBUILT 3 // per thread
 #define MAXROOTS 1000
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -102,7 +102,8 @@
 
 
 if (p-h_original) { /* fast path */
-fprintf(stderr, stm_id(%p) has orig fst: %p\n, p, p-h_original);
+fprintf(stderr, stm_id(%p) has orig fst: %p\n, 
+p, (gcptr)p-h_original);
 return p-h_original;
 } 
 else if (!(p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED)
@@ -122,7 +123,8 @@
 */
 if (p-h_original) { /* maybe now? */
 result = p-h_original;
-fprintf(stderr, stm_id(%p) has orig: %p\n, p, p-h_original);
+fprintf(stderr, stm_id(%p) has orig: %p\n, 
+p, (gcptr)p-h_original);
 }
 else if (p-h_tid  GCFLAG_OLD) {
 /* it must be this exact object */
@@ -141,7 +143,7 @@
 
 result = (revision_t)B;
 fprintf(stderr, stm_id(%p) young, pfp, use backup %p\n, 
-p, p-h_original);
+p, (gcptr)p-h_original);
 }
 else {
 gcptr O = stmgc_duplicate_old(p);
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -42,6 +42,9 @@
 #define PREBUILT_REVISION  ...
 
 gcptr stm_allocate(size_t size, unsigned int tid);
+revision_t stm_hash(gcptr);
+revision_t stm_id(gcptr);
+revision_t stm_pointer_equal(gcptr, gcptr);
 void stm_push_root(gcptr);
 gcptr stm_pop_root(void);
 void stm_set_max_aborts(int max_aborts);
@@ -108,6 +111,7 @@
 #define GCFLAG_NURSERY_MOVED ...
 #define GCFLAG_STUB  ...
 #define GCFLAG_PRIVATE_FROM_PROTECTED  ...
+#define GCFLAG_HAS_ID...
 #define ABRT_MANUAL  ...
 typedef struct { ...; } page_header_t;
 ''')
@@ -607,4 +611,10 @@
 assert (r % 4) == 0
 return ffi.cast(gcptr, r)
 
+def follow_original(p):
+r = p.h_original
+assert (r % 4) == 0
+return ffi.cast(gcptr, r)
+
+
 nrb_protected = ffi.cast(gcptr, -1)
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
@@ -198,6 +198,49 @@
 assert p4 == p2
 assert list_of_read_objects() == [p2]
 
+
+def test_id_young_to_old():
+# move out of nursery with shadow original
+p = nalloc(HDR)
+assert p.h_original == 0
+pid = lib.stm_id(p)
+assert p.h_tid  GCFLAG_HAS_ID
+porig = follow_original(p)
+assert porig.h_tid  GCFLAG_OLD
+lib.stm_push_root(p)
+minor_collect()
+p = lib.stm_pop_root()
+assert not lib.in_nursery(p)
+assert pid == lib.stm_id(p)
+
+def test_id_private_from_protected():
+# read and write from protected
+p = oalloc(HDR)
+pid = lib.stm_id(p)
+porig = follow_original(p)
+# impl detail {
+# old objects have id==itself, if not set differently
+assert porig == ffi.NULL
+assert ffi.cast(gcptr, pid) == p
+# }
+
+p1 = oalloc(HDR)
+p1id = lib.stm_id(p1)
+p1r = lib.stm_read_barrier(p1)
+assert lib.stm_id(p1r) == p1id
+p1w = lib.stm_write_barrier(p1)
+assert lib.stm_id(p1w) == p1id
+
+p2 = oalloc(HDR)
+p2w = lib.stm_write_barrier(p2)
+p2id = lib.stm_id(p2)
+assert p2id == lib.stm_id(p2w)
+# impl detail {
+assert p2w.h_original == 0
+assert follow_revision(p2w).h_original == lib.stm_id(p2w)
+# }
+
+
 def test_stealing_old():
 p = palloc(HDR + WORD)
 plist = [p]
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add some comments; add hash_mangling

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r248:78c58b8aabfa
Date: 2013-06-24 09:10 +0200
http://bitbucket.org/pypy/stmgc/changeset/78c58b8aabfa/

Log:add some comments; add hash_mangling

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -88,13 +88,45 @@
 }
 
 //
-
+/* Each object has a h_original pointer to an old copy of 
+   the same object (e.g. an old revision), the original. 
+   The memory location of this old object is used as the ID 
+   for this object. If h_original is NULL *and* it is an
+   old object copy, it itself is the original. This invariant
+   must be upheld by all code dealing with h_original.
+   The original copy must never be moved again. Also, it may
+   be just a stub-object.
+   
+   If we want the ID of an object which is still young,
+   we must preallocate an old shadow-original that is used
+   as the target of the young object in a minor collection.
+   In this case, we set the HAS_ID flag on the young obj
+   to notify minor_collect.
+   This flag can be lost if the young obj is stolen. Then
+   the stealing thread uses the shadow-original itself and
+   minor_collect must not overwrite it again.
+   Also, if there is already a backup-copy around, we use
+   this instead of allocating another old object to use as 
+   the shadow-original.
+ */
 
 revision_t stm_hash(gcptr p)
 {
 return stm_id(p);
 }
 
+
+static revision_t mangle_hash(revision_t n)
+{
+/* To hash pointers in dictionaries.  Assumes that i shows some
+   alignment (to 4, 8, maybe 16 bytes), so we use the following
+   formula to avoid the trailing bits being always 0.
+   This formula is reversible: two different values of 'i' will
+   always give two different results.
+*/
+return n ^ (n  4);
+}
+
 revision_t stm_id(gcptr p)
 {
 struct tx_descriptor *d = thread_descriptor;
@@ -104,15 +136,23 @@
 if (p-h_original) { /* fast path */
 fprintf(stderr, stm_id(%p) has orig fst: %p\n, 
 p, (gcptr)p-h_original);
-return p-h_original;
+return mangle_hash(p-h_original);
 } 
 else if (!(p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED)
 (p-h_tid  GCFLAG_OLD)) {
 /* we can be sure that p-h_original doesn't
-   get set during the if and the else-if */
+   get set during the if and the else-if 
+   
+   XXX: check for priv_from_protected may not be 
+   necessary. only if this func may be called on 
+   another thread's young objects that are made 
+   old at the same time, and we see the OLD flag 
+   before h_original has been set.
+*/
 fprintf(stderr, stm_id(%p) is old, orig=0 fst: %p\n, p, p);
-return (revision_t)p;
+return mangle_hash((revision_t)p);
 }
+
 
 spinlock_acquire(d-public_descriptor-collection_lock, 'I');
 /* old objects must have an h_original xOR be
@@ -137,7 +177,6 @@
 if (p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
 gcptr B = (gcptr)p-h_revision;
 /* don't set, otherwise nursery will copy over backup */
-//p-h_tid |= GCFLAG_HAS_ID; // see AbortPrivateFromProtected
 p-h_original = (revision_t)B;
 // B-h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
 
@@ -157,7 +196,7 @@
 }
 
 spinlock_release(d-public_descriptor-collection_lock);
-return result;
+return mangle_hash(result);
 }
 
 revision_t stm_pointer_equal(gcptr p1, gcptr p2)
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -93,7 +93,6 @@
 assert(!(L-h_tid  GCFLAG_HAS_ID));
 /* original must be L */
 B-h_original = (revision_t)L;
-assert(0);
 }
 else {
 /* we can make the backup the original
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
@@ -216,12 +216,10 @@
 def test_id_private_from_protected():
 # read and write from protected
 p = oalloc(HDR)
-pid = lib.stm_id(p)
 porig = follow_original(p)
 # impl detail {
 # old objects have id==itself, if not set differently
 assert porig == ffi.NULL
-assert ffi.cast(gcptr, pid) == p
 # }
 
 p1 = oalloc(HDR)
@@ -237,7 +235,6 @@
 assert p2id == lib.stm_id(p2w)
 # impl detail {
 assert p2w.h_original == 0
-assert follow_revision(p2w).h_original == lib.stm_id(p2w)
 # }
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add multiple thread start/finish to demo_random

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r249:c73629c0bb3c
Date: 2013-06-24 09:41 +0200
http://bitbucket.org/pypy/stmgc/changeset/c73629c0bb3c/

Log:add multiple thread start/finish to demo_random

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -13,7 +13,8 @@
 
 
 #define NUMTHREADS 4
-#define STEPS 100
+#define STEPS_PER_THREAD 5000
+#define THREAD_STARTS 100 // how many restarts of threads
 #define NUMROOTS 10 // per thread
 #define PREBUILT 3 // per thread
 #define MAXROOTS 1000
@@ -234,7 +235,7 @@
 {
 int i;
 td.thread_seed = default_seed;
-td.steps_left = STEPS;
+td.steps_left = STEPS_PER_THREAD;
 td.interruptible = 0;
 
 td.num_roots = PREBUILT + NUMROOTS;
@@ -250,8 +251,6 @@
 
 gcptr do_step(gcptr p)
 {
-fprintf(stdout, #);
-
 nodeptr w_r, w_sr;
 gcptr _r, _sr;
 int num, k;
@@ -394,6 +393,10 @@
 gcptr p = NULL;
 while (td.steps_left) {
 td.steps_left--;
+
+if (td.steps_left % 8 == 0)
+fprintf(stdout, #);
+
 p = do_step(p);
 
 if (p == (gcptr)-1)
@@ -453,13 +456,20 @@
 status = sem_init(done, 0, 0);
 assert(status == 0);
 
-for (i = 0; i  NUMTHREADS; i++)
+int thread_starts = NUMTHREADS * THREAD_STARTS;
+for (i = 0; i  NUMTHREADS; i++) {
 newthread(demo, NULL);
+thread_starts--;
+}
 
-for (i=0; i  NUMTHREADS; i++) {
+for (i=0; i  NUMTHREADS * THREAD_STARTS; i++) {
 status = sem_wait(done);
 assert(status == 0);
 printf(thread finished\n);
+if (thread_starts) {
+thread_starts--;
+newthread(demo, NULL);
+}
 }
 
 return 0;
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: remove assert

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r252:6effbf62467f
Date: 2013-06-24 10:48 +0200
http://bitbucket.org/pypy/stmgc/changeset/6effbf62467f/

Log:remove assert

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1501,8 +1501,11 @@
   assert(descriptor_array_free_list = 0);
   assert(pd-stolen_objects.size == 0);
   assert(pd-stolen_young_stubs.size == 0);
-  assert(pd-collection_lock == 0);
   pd-shutdown = 0;
+  /* there may be a thread holding the collection lock
+ because it steals a stub belonging to the thread
+ that previously owned this descriptor.
+  */
   }
   else {
   /* no item in the free list */
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: fix

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r253:500b2ca07505
Date: 2013-06-24 12:30 +0200
http://bitbucket.org/pypy/stmgc/changeset/500b2ca07505/

Log:fix

diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -160,19 +160,18 @@
 /* use id-copy for us */
 O = (gcptr)L-h_original;
 L-h_tid = ~GCFLAG_HAS_ID;
-L-h_revision = (revision_t)O;
-copy_to_old_id_copy(L, (gcptr)L-h_original);
+copy_to_old_id_copy(L, O);
+O-h_original = 0;
 } else {
 /* Copy the object out of the other thread's nursery, 
if needed */
 O = stmgc_duplicate_old(L);
-L-h_revision = (revision_t)O;
 
-/* young and without original?
-   we may lose the HAS_ID flag like above */
+/* young and without original? */
 if (!(L-h_original))
 L-h_original = (revision_t)O;
 }
+L-h_revision = (revision_t)O;
 
 L-h_tid |= GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED;
 /* subtle: we need to remove L from the fxcache of the target
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
@@ -22,6 +22,7 @@
 assert p.h_revision == r
 assert p.h_tid == lib.gettid(p) | 0# no GC flags
 assert classify(p) == private
+assert lib.stm_id(p) != 0
 
 def test_write_barrier_private():
 p = nalloc(HDR)
@@ -84,17 +85,20 @@
GCFLAG_PUBLIC |
GCFLAG_PREBUILT_ORIGINAL)
 assert classify(p) == public
+assert lib.stm_id(p) != 0
 
 def test_prebuilt_object_to_private():
 p = palloc(HDR)
 flags = p.h_tid
 assert (flags  GCFLAG_PUBLIC_TO_PRIVATE) == 0
+pid = lib.stm_id(p)
 assert classify(p) == public
 p2 = lib.stm_write_barrier(p)
 assert p2 != p
 assert classify(p) == public
 assert classify(p2) == private
 assert p.h_tid == flags | GCFLAG_PUBLIC_TO_PRIVATE
+assert pid == lib.stm_id(p2)
 
 def test_commit_change_to_prebuilt_object():
 p = palloc(HDR + WORD)
@@ -155,6 +159,7 @@
 
 def test_read_barrier_public_to_private():
 p = palloc(HDR)
+pid = lib.stm_id(p)
 p2 = lib.stm_write_barrier(p)
 assert p2 != p
 assert classify(p) == public
@@ -165,6 +170,7 @@
 p3 = lib.stm_read_barrier(p)
 assert p3 == p2
 assert list_of_read_objects() == [p]
+assert pid == lib.stm_id(p2)
 
 def test_read_barrier_handle_protected():
 p = palloc(HDR)
@@ -231,8 +237,8 @@
 
 p2 = oalloc(HDR)
 p2w = lib.stm_write_barrier(p2)
-p2id = lib.stm_id(p2)
-assert p2id == lib.stm_id(p2w)
+p2id = lib.stm_id(p2w)
+assert p2id == lib.stm_id(p2)
 # impl detail {
 assert p2w.h_original == 0
 # }
@@ -255,6 +261,8 @@
 lib.rawsetlong(p1, 0, 2782172)
 lib.stm_commit_transaction()
 lib.stm_begin_inevitable_transaction()
+p1id = lib.stm_id(p1)
+assert p1id == lib.stm_id(p)
 assert classify(p) == public
 assert classify(p1) == protected
 plist.append(p1) # now p's most recent revision is protected
@@ -265,9 +273,11 @@
 assert classify(p1) == public
 assert lib.stm_read_barrier(p) == p1
 assert lib.stm_read_barrier(p1) == p1
+assert lib.stm_id(p1) == p1id
 def f2(r):
 r.wait(2)
 p2 = lib.stm_read_barrier(p)# steals
+assert lib.stm_id(p) == lib.stm_id(p2)
 assert classify(p2) == public
 assert lib.rawgetlong(p2, 0) == 2782172
 assert p2 == lib.stm_read_barrier(p)# short-circuit h_revision
@@ -297,8 +307,10 @@
 plist.append(p1) # now p's most recent revision is protected
 assert classify(follow_revision(p)) == stub
 assert p1.h_revision  1
+p1id = lib.stm_id(p1)
 r.set(2)
 r.wait(3)
+assert p1id == lib.stm_id(p1)
 assert classify(p1) == public
 assert (p1.h_revision  1) == 0# outdated
 p2 = ffi.cast(gcptr, p1.h_revision)
@@ -310,6 +322,7 @@
 def f2(r):
 r.wait(2)
 p2 = lib.stm_read_barrier(p)# steals
+assert lib.stm_id(p) == lib.stm_id(p2)
 assert classify(p2) == public
 assert lib.rawgetlong(p2, 0) == 2782172
 assert p2 == lib.stm_read_barrier(p)# short-circuit h_revision
@@ -425,6 +438,8 @@
 def test_stub_for_refs_from_stolen(old=False):
 p = palloc_refs(1)
 qlist = []
+qid = []
+pid = []
 def f1(r):
 q1 = nalloc(HDR + WORD)
 if old:
@@ -446,6 +461,16 @@
 assert classify(p1) == protected
 assert classify(follow_revision(p)) == stub
 assert p1.h_revision  1
+pid.append(lib.stm_id(p1))
+assert classify(q1) == protected

[pypy-commit] stmgc default: more tests

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r254:78560280729a
Date: 2013-06-24 13:42 +0200
http://bitbucket.org/pypy/stmgc/changeset/78560280729a/

Log:more tests

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -176,7 +176,7 @@
backup, if exists */
 if (p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
 gcptr B = (gcptr)p-h_revision;
-/* don't set, otherwise nursery will copy over backup */
+/* don't set HAS_ID, otherwise nursery will copy over backup */
 p-h_original = (revision_t)B;
 // B-h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
 
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
@@ -496,3 +496,77 @@
 
 def test_stub_for_refs_from_stolen_old():
 test_stub_for_refs_from_stolen(old=True)
+
+
+def id_with_stealing(a=0, b=0):
+p = palloc_refs(2)
+qlist = []
+rlist = []
+qid = []
+pid = []
+rid = []
+def f1(r):
+r1 = nalloc(HDR)
+q1 = nalloc(HDR)
+p1 = lib.stm_write_barrier(p)   # private copy
+qlist.append(q1)
+rlist.append(r1)
+if a:
+# id on young priv
+qid.append(lib.stm_id(q1))
+assert q1.h_tid  GCFLAG_HAS_ID
+if b:
+# id on pub_to_priv
+assert follow_original(p1) == p
+pid.append(lib.stm_id(p1))
+assert not (p1.h_tid  GCFLAG_HAS_ID)
+lib.setptr(p1, 0, q1)
+lib.setptr(p1, 1, r1)
+lib.stm_commit_transaction()
+lib.stm_begin_inevitable_transaction()
+# p old public - stub - p1 young prot
+# q1 young prot, r1 young prot
+if not a:
+# id on young prot
+qid.append(lib.stm_id(q1))
+assert q1.h_tid  GCFLAG_HAS_ID
+if not b:
+# id on young prot
+assert follow_original(p1) == p
+pid.append(lib.stm_id(p1))
+assert not (p1.h_tid  GCFLAG_HAS_ID)
+
+r1w = lib.stm_write_barrier(r1) # priv_from_prot
+assert r1w.h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
+rid.append(lib.stm_id(r1w))
+assert not (r1w.h_tid  GCFLAG_HAS_ID) # use backup
+assert follow_original(r1w) == follow_revision(r1w)
+
+r.set(2)
+r.wait(3) # wait until the other thread really started
+def f2(r):
+r.wait(2)
+r.set(3)
+
+p2 = lib.stm_read_barrier(p)# steals
+assert pid[-1] == lib.stm_id(p2)
+
+r2 = lib.getptr(p2, 1)
+r3 = lib.stm_read_barrier(r2)
+assert lib.stm_id(r3) == rid[-1]
+
+q2 = lib.getptr(p2, 0)
+assert lib.stm_id(q2) == qid[-1]
+
+q3 = lib.stm_read_barrier(q2)
+assert lib.stm_id(q3) == qid[-1]
+
+run_parallel(f1, f2)
+
+def test_id_with_stealing():
+id_with_stealing(1, 1)
+id_with_stealing(1, 0)
+id_with_stealing(0, 1)
+id_with_stealing(0, 0)
+
+
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add support for predefined hash in prebuilt objects

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r256:67200f7bca96
Date: 2013-06-24 14:39 +0200
http://bitbucket.org/pypy/stmgc/changeset/67200f7bca96/

Log:add support for predefined hash in prebuilt objects

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -489,9 +489,13 @@
   /* note that stmgc_duplicate() usually returns a young object, but may
  return an old one if the nursery is full at this moment. */
   gcptr L = stmgc_duplicate(R);
-  if (!(L-h_original)) {
-/* if we don't have an original object yet,
- it must be the old public R */
+  if (!(L-h_original) || L-h_tid  GCFLAG_PREBUILT_ORIGINAL) {
+/* if we don't have an original object yet, it must be the 
+   old public R 
+   Also, prebuilt objects may have a predefined hash stored
+   in the h_original. - point to the original copy on copies
+   of the prebuilt.
+*/
 assert(R-h_tid  GCFLAG_OLD); // if not, force stm_id??
 L-h_original = (revision_t)R;
   }
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -110,12 +110,6 @@
the shadow-original.
  */
 
-revision_t stm_hash(gcptr p)
-{
-return stm_id(p);
-}
-
-
 static revision_t mangle_hash(revision_t n)
 {
 /* To hash pointers in dictionaries.  Assumes that i shows some
@@ -127,13 +121,40 @@
 return n ^ (n  4);
 }
 
+
+revision_t stm_hash(gcptr p)
+{
+/* Prebuilt objects may have a specific hash stored in an extra 
+   field. For now, we will simply always follow h_original and
+   see, if it is a prebuilt object (XXX: maybe propagate a flag
+   to all copies of a prebuilt to avoid this cache miss).
+ */
+if (p-h_original) {
+if (p-h_tid  GCFLAG_PREBUILT_ORIGINAL) {
+return p-h_original;
+}
+gcptr orig = (gcptr)p-h_original;
+if ((orig-h_tid  GCFLAG_PREBUILT_ORIGINAL)  orig-h_original) {
+return orig-h_original;
+}
+}
+return stm_id(p);
+}
+
+
 revision_t stm_id(gcptr p)
 {
 struct tx_descriptor *d = thread_descriptor;
 revision_t result;
 
-
 if (p-h_original) { /* fast path */
+if (p-h_tid  GCFLAG_PREBUILT_ORIGINAL) {
+/* h_original may contain a specific hash value,
+   but in case of the prebuilt original version, 
+   its memory location is the id */
+return mangle_hash((revision_t)p);
+}
+
 fprintf(stderr, stm_id(%p) has orig fst: %p\n, 
 p, (gcptr)p-h_original);
 return mangle_hash(p-h_original);
@@ -152,6 +173,7 @@
 fprintf(stderr, stm_id(%p) is old, orig=0 fst: %p\n, p, p);
 return mangle_hash((revision_t)p);
 }
+
 
 
 spinlock_acquire(d-public_descriptor-collection_lock, 'I');
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -91,6 +91,7 @@
 void rawsetlong(gcptr, long, long);
 
 gcptr pseudoprebuilt(size_t size, int tid);
+gcptr pseudoprebuilt_with_hash(size_t size, int tid, revision_t hash);
 revision_t get_private_rev_num(void);
 revision_t get_start_time(void);
 void *my_stub_thread(void);
@@ -217,6 +218,13 @@
 return x;
 }
 
+gcptr pseudoprebuilt_with_hash(size_t size, int tid, revision_t hash)
+{
+gcptr x = pseudoprebuilt(size, tid);
+x-h_original = hash;
+return x;
+}
+
 revision_t get_start_time(void)
 {
 return thread_descriptor-start_time;
@@ -473,15 +481,22 @@
 assert rawgetptr(p, i) == ffi.NULL   # must already be zero-filled
 return p
 
-def palloc(size):
+def palloc(size, prehash=None):
 Get a ``prebuilt'' object.
-p = lib.pseudoprebuilt(size, 42 + size)
+if prehash is None:
+p = lib.pseudoprebuilt(size, 42 + size)
+else:
+p = lib.pseudoprebuilt_with_hash(size, 42 + size, prehash)
 assert p.h_revision == 1
 return p
 
-def palloc_refs(nrefs):
+def palloc_refs(nrefs, prehash=None):
 Get a ``prebuilt'' object with nrefs pointers.
-p = lib.pseudoprebuilt(HDR + WORD * nrefs, 421 + nrefs)
+if prehash is None:
+p = lib.pseudoprebuilt(HDR + WORD * nrefs, 421 + nrefs)
+else:
+p = lib.pseudoprebuilt_with_hash(HDR + WORD * nrefs,
+ 421 + nrefs, prehash)
 return p
 
 gettid = lib.gettid
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
@@ -569,4 +569,44 @@
 id_with_stealing(0, 1)
 id_with_stealing(0, 0)
 
+
+def test_prehash_simple():
+p = palloc(HDR, 99)
+assert lib.stm_hash(p) == 99
+assert lib.stm_id(p) != lib.stm_hash(p)
+pr = lib.stm_read_barrier(p)
+assert lib.stm_hash(pr) == 99
+assert lib.stm_id(p) == lib.stm_id(pr)
+pw = lib.stm_write_barrier(p)
+assert lib.stm_hash(pw) == 99
+assert lib.stm_id(p) == lib.stm_id(pw)
+lib.stm_push_root(pw)
+

[pypy-commit] stmgc default: merge

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r259:076863fce4d4
Date: 2013-06-24 15:01 +0200
http://bitbucket.org/pypy/stmgc/changeset/076863fce4d4/

Log:merge

diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -383,3 +383,33 @@
 p1 = lib.stm_pop_root()
 check_not_free(p1)
 check_not_free(lib.getptr(p1, 0))
+
+def test_prebuilt_modified_during_transaction():
+p1 = palloc(HDR)
+p2 = nalloc_refs(1)
+lib.setptr(p2, 0, p1)
+lib.stm_push_root(p2)
+major_collect()
+major_collect()
+p1b = lib.stm_write_barrier(p1)
+assert p1b != p1
+major_collect()
+lib.stm_pop_root()
+p1b = lib.stm_read_barrier(p1)
+check_not_free(p1b)
+
+def test_prebuilt_modified_later():
+p1 = palloc(HDR)
+p2 = nalloc_refs(1)
+lib.setptr(p2, 0, p1)
+lib.stm_push_root(p2)
+major_collect()
+major_collect()
+p1b = lib.stm_write_barrier(p1)
+assert p1b != p1
+lib.stm_commit_transaction()
+lib.stm_begin_inevitable_transaction()
+major_collect()
+lib.stm_pop_root()
+p1b = lib.stm_read_barrier(p1)
+check_not_free(p1b)
diff --git a/c4/test/test_random.py b/c4/test/test_random.py
--- a/c4/test/test_random.py
+++ b/c4/test/test_random.py
@@ -522,4 +522,4 @@
 def test_more_multi_thread():
 #py.test.skip(more random tests)
 for i in range(200):
-yield test_multi_thread, 1690 + i
+yield test_multi_thread, 1751 + i
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add hash to demo_random, crashes sometimes..

2013-06-24 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r263:05dae094fa06
Date: 2013-06-24 16:14 +0200
http://bitbucket.org/pypy/stmgc/changeset/05dae094fa06/

Log:add hash to demo_random, crashes sometimes..

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -29,6 +29,7 @@
 struct stm_object_s hdr;
 long value;
 revision_t id;
+revision_t hash;
 struct node *next;
 };
 typedef struct node * nodeptr;
@@ -84,7 +85,14 @@
 gcptr x = calloc(1, size);
 x-h_tid = PREBUILT_FLAGS | tid;
 x-h_revision = PREBUILT_REVISION;
-x-h_original = 0;
+return x;
+}
+
+gcptr allocate_pseudoprebuilt_with_hash(size_t size, int tid,
+revision_t hash)
+{
+gcptr x = allocate_pseudoprebuilt(size, tid);
+x-h_original = hash;
 return x;
 }
 
@@ -240,8 +248,17 @@
 
 td.num_roots = PREBUILT + NUMROOTS;
 for (i = 0; i  PREBUILT; i++) {
-td.roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
-  GCTID_STRUCT_NODE);
+if (i % 3 == 0) {
+td.roots[i] = allocate_pseudoprebuilt_with_hash(
+  sizeof(struct node), 
+  GCTID_STRUCT_NODE,
+  i);
+((nodeptr)td.roots[i])-hash = i;
+}
+else {
+td.roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
+  GCTID_STRUCT_NODE);
+}
 }
 for (i = PREBUILT; i  PREBUILT + NUMROOTS; i++) {
 td.roots[i] = (gcptr)allocate_node();
@@ -251,17 +268,19 @@
 
 gcptr do_step(gcptr p)
 {
-nodeptr w_r, w_sr;
-gcptr _r, _sr;
+nodeptr w_r, w_sr, w_t;
+gcptr _r, _sr, _t;
 int num, k;
 
+_t = NULL;
 num = get_rand(td.num_roots);
 _r = td.roots[num];
-
+
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
 
-k = get_rand(17);
+k = get_rand(19);
+check(p);
 
 switch (k) {
 case 0: // remove a root
@@ -323,28 +342,42 @@
 pop_roots();
 p = NULL;
 break;
-case 15: /* test stm_id on non-shared roots */
-w_r = (nodeptr)read_barrier(_r);
-if (w_r-id) {
-assert(w_r-id == stm_id((gcptr)w_r));
-assert(w_r-id == stm_id((gcptr)_r));
+case 15: /* test stm_id on (non-)shared roots */
+_t = _r;
+case 16:
+if (!_t)
+_t = _sr;
+w_t = (nodeptr)read_barrier(_t);
+if (w_t-id) {
+assert(w_t-id == stm_id((gcptr)w_t));
+assert(w_t-id == stm_id((gcptr)_t));
 } 
 else {
-w_r = (nodeptr)write_barrier(_r);
-w_r-id = stm_id((gcptr)w_r);
-assert(w_r-id == stm_id((gcptr)_r));
+w_t = (nodeptr)write_barrier(_t);
+w_t-id = stm_id((gcptr)w_t);
+assert(w_t-id == stm_id((gcptr)_t));
 }
-case 16: /* test stm_id on shared roots */
-w_sr = (nodeptr)read_barrier(_sr);
-if (w_sr-id) {
-assert(w_sr-id == stm_id((gcptr)w_sr));
-assert(w_sr-id == stm_id((gcptr)_sr));
-} 
+break;
+case 17: /* test stm_hash on (non-)shared roots */
+_t = _r;
+case 18:
+if (!_t)
+_t = _sr;
+w_t = (nodeptr)read_barrier(_t);
+if (w_t-hash) {
+assert(w_t-hash == stm_hash((gcptr)w_t));
+assert(w_t-hash == stm_hash((gcptr)_t));
+}
 else {
-w_sr = (nodeptr)write_barrier(_sr);
-w_sr-id = stm_id((gcptr)w_sr);
-assert(w_sr-id == stm_id((gcptr)_sr));
+w_t = (nodeptr)write_barrier(_t);
+w_t-hash = stm_hash((gcptr)w_t);
+assert(w_t-hash == stm_hash((gcptr)_t));
 }
+if (w_t-hash  PREBUILT || w_t-hash  SHARED_ROOTS) {
+// should be with predefined hash
+assert (stm_id((gcptr)w_t) != stm_hash((gcptr)w_t));
+}
+break;
 }
 return p;
 }
@@ -449,8 +482,17 @@
 default_seed = time(NULL) / 3600 / 24;
 
 for (i = 0; i  SHARED_ROOTS; i++) {
-shared_roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
-  GCTID_STRUCT_NODE);
+if (i % 3 == 0) {
+shared_roots[i] = allocate_pseudoprebuilt_with_hash(
+  sizeof(struct node), 
+  GCTID_STRUCT_NODE,
+  i);
+((nodeptr)shared_roots[i])-hash = i;
+}
+else {
+shared_roots[i] = allocate_pseudoprebuilt(sizeof(struct node), 
+  GCTID_STRUCT_NODE);
+}
 }
 
 status = sem_init(done, 0, 0);

[pypy-commit] stmgc default: merge

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r274:5634ab8d11f6
Date: 2013-06-25 14:01 +0200
http://bitbucket.org/pypy/stmgc/changeset/5634ab8d11f6/

Log:merge

diff --git a/c4/Makefile b/c4/Makefile
--- a/c4/Makefile
+++ b/c4/Makefile
@@ -2,14 +2,16 @@
 # Makefile for the demos.
 #
 
+DEBUG_EXE = debug-demo1 debug-demo2 debug-demo_random
 BUILD_EXE = build-demo1 build-demo2 build-demo_random
-DEBUG_EXE = debug-demo1 debug-demo2 debug-demo_random
+RELEASE_EXE = release-demo1 release-demo2 release-demo_random
 
-build: $(BUILD_EXE)
-debug: $(DEBUG_EXE)
+debug: $(DEBUG_EXE)   # with prints and asserts
+build: $(BUILD_EXE)   # without prints, but with asserts
+release: $(RELEASE_EXE)   # without prints nor asserts
 
 clean:
-   rm -f $(BUILD_EXE) $(DEBUG_EXE)
+   rm -f $(BUILD_EXE) $(DEBUG_EXE) $(RELEASE_EXE)
 
 
 H_FILES = atomic_ops.h stmgc.h stmimpl.h \
@@ -29,5 +31,8 @@
 debug-%: %.c ${H_FILES} ${C_FILES}
gcc -lrt -pthread ${DEBUG} $ -o debug-$* -Wall ${C_FILES}
 
+release-%: %.c ${H_FILES} ${C_FILES} stmgc.c
+   gcc -lrt -pthread -DNDEBUG -O2 -g $ -o release-$* -Wall stmgc.c
+
 test-%:
./$* 2/dev/null | grep check ok
diff --git a/c4/demo1.c b/c4/demo1.c
--- a/c4/demo1.c
+++ b/c4/demo1.c
@@ -11,7 +11,11 @@
 #include fprintcolor.h
 
 
-#define UPPER_BOUND 100
+#ifdef _GC_DEBUG
+# define UPPER_BOUND 100
+#else
+# define UPPER_BOUND 5000
+#endif
 #define NUMTHREADS  4
 
 
@@ -134,7 +138,8 @@
 stm_finalize();
 
 status = sem_post(done);
-assert(status == 0);
+if (status != 0)
+stm_fatalerror(status != 0\n);
 return NULL;
 }
 
@@ -158,7 +163,8 @@
 {
   pthread_t th;
   int status = pthread_create(th, NULL, func, arg);
-  assert(status == 0);
+  if (status != 0)
+  stm_fatalerror(status != 0\n);
   pthread_detach(th);
   printf(started new thread\n);
 }
@@ -168,7 +174,8 @@
   int i, status;
 
   status = sem_init(done, 0, 0);
-  assert(status == 0);
+  if (status != 0)
+  stm_fatalerror(status != 0\n);
 
   for (i = 0; i  NUMTHREADS; i++)
 newthread(demo1, NULL);
@@ -176,7 +183,8 @@
   for (i=0; i  NUMTHREADS; i++)
 {
   status = sem_wait(done);
-  assert(status == 0);
+  if (status != 0)
+  stm_fatalerror(status != 0\n);
   printf(thread finished\n);
 }
 
diff --git a/c4/demo2.c b/c4/demo2.c
--- a/c4/demo2.c
+++ b/c4/demo2.c
@@ -97,23 +97,9 @@
 r_current = (struct node*)stm_read_barrier((gcptr)r_next);
 r_next = (struct node*)stm_read_barrier((gcptr)tmp);
 }
-// results from consecutive read_barriers can differ. needs Ptr_Eq()
-int i = 0;
-while (!(stm_read_barrier((gcptr)r_prev-next) ==
- stm_read_barrier((gcptr)r_current) 
- stm_read_barrier((gcptr)r_current-next) ==
- stm_read_barrier((gcptr)r_next))) {
-asm volatile (pause:::memory);  /* smp_spinloop() */
-i++;
-assert(i  100);
-}
-// for now:
-assert(((nodeptr)stm_read_barrier((gcptr)r_prev-next))-value 
-   == r_current-value
-
-   ((nodeptr)stm_read_barrier((gcptr)r_current-next))-value
-   == r_next-value);
-
+assert(stm_pointer_equal((gcptr)r_prev-next, (gcptr)r_current));
+assert(stm_pointer_equal((gcptr)r_current-next, (gcptr)r_next));
+
 r_prev = r_current;
 r_current = r_next;
 r_next = r_next-next;
@@ -154,7 +140,8 @@
 void final_check(void)
 {
 long sum;
-
+
+printf(final check\n);
 stm_initialize();
 
 sum = check_sorted();
@@ -171,7 +158,8 @@
 {
 pthread_t th;
 int status = pthread_create(th, NULL, func, arg);
-assert(status == 0);
+if (status != 0)
+stm_fatalerror(newthread: pthread_create failure\n);
 pthread_detach(th);
 printf(started new thread\n);
 }
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -473,7 +473,8 @@
 {
 pthread_t th;
 int status = pthread_create(th, NULL, func, arg);
-assert(status == 0);
+if (status != 0)
+stm_fatalerror(newthread: pthread_create failure\n);
 pthread_detach(th);
 printf(started new thread\n);
 }
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -305,6 +305,7 @@
 
 static void _check_flags(gcptr P)
 {
+#ifndef NDEBUG
   struct tx_descriptor *d = thread_descriptor;
   if (P-h_tid  GCFLAG_STUB)
 {
@@ -322,6 +323,7 @@
   assert(is_old);
   dprintf((O ));
 }
+#endif
 }
 
 gcptr _stm_nonrecord_barrier(gcptr P)
@@ -962,7 +964,6 @@
 
 static void CancelLocks(struct tx_descriptor *d)
 {
-  revision_t my_lock = d-my_lock;
   wlog_t *item;
 
   if (!g2l_any_entry(d-public_to_private))
@@ -984,7 +985,7 @@
 
   if (v == expected)
 {
-  assert(R-h_revision != my_lock);
+  assert(R-h_revision != d-my_lock);
   break;/* done */

[pypy-commit] stmgc default: do not use backup as shadow-original, always use additional shadow

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r273:d01dac528994
Date: 2013-06-25 14:01 +0200
http://bitbucket.org/pypy/stmgc/changeset/d01dac528994/

Log:do not use backup as shadow-original, always use additional shadow

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -55,7 +55,6 @@
 unsigned int thread_seed;
 gcptr roots[MAXROOTS];
 gcptr roots_outside_perform[MAXROOTS];
-gcptr current_root;
 int num_roots;
 int num_roots_outside_perform;
 int steps_left;
@@ -68,6 +67,12 @@
 int classify(gcptr p);
 void check(gcptr p);
 
+static int is_private(gcptr P)
+{
+  return (P-h_revision == stm_private_rev_num) ||
+(P-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED);
+}
+
 int get_rand(int max)
 {
 return (int)(rand_r(td.thread_seed) % (unsigned int)max);
@@ -101,7 +106,8 @@
 int i;
 for (i = 0; i  td.num_roots; i++) {
 check(td.roots[i]);
-stm_push_root(td.roots[i]);
+if (td.roots[i])
+stm_push_root(td.roots[i]);
 }
 }
 
@@ -109,7 +115,8 @@
 {
 int i;
 for (i = td.num_roots - 1; i = 0; i--) {
-td.roots[i] = stm_pop_root();
+if (td.roots[i])
+td.roots[i] = stm_pop_root();
 check(td.roots[i]);
 }
 }
@@ -173,6 +180,7 @@
 check(p);
 w = stm_write_barrier(p);
 check(w);
+assert(is_private(w));
 }
 return w;
 }
@@ -351,7 +359,7 @@
 if (w_t-id) {
 assert(w_t-id == stm_id((gcptr)w_t));
 assert(w_t-id == stm_id((gcptr)_t));
-} 
+}
 else {
 w_t = (nodeptr)write_barrier(_t);
 w_t-id = stm_id((gcptr)w_t);
@@ -425,9 +433,7 @@
 int run_me()
 {
 gcptr p = NULL;
-while (td.steps_left) {
-td.steps_left--;
-
+while (td.steps_left--0) {
 if (td.steps_left % 8 == 0)
 fprintf(stdout, #);
 
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1120,14 +1120,6 @@
 break;
 }
 }  
-  else if (P-h_original == (revision_t)B) {
-/* The backup is the id object */
-assert(!(P-h_tid  GCFLAG_HAS_ID));
-
-B-h_tid = ~GCFLAG_BACKUP_COPY;
-B-h_tid |= GCFLAG_PUBLIC;
-B-h_revision = (revision_t)P;
-  }
   else
 {
   stmgcpage_free(B);
@@ -1159,7 +1151,7 @@
 {
   assert(!(B-h_tid  GCFLAG_BACKUP_COPY));
   P-h_tid |= GCFLAG_PUBLIC;
-  P-h_tid = ~GCFLAG_HAS_ID; // just in case
+  assert(!(P-h_tid  GCFLAG_HAS_ID));
   if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
   /* P becomes a public outdated object.  It may create an
  exception documented in doc-objects.txt: a public but young
@@ -1168,24 +1160,16 @@
  stealing will follow its h_revision (to B).
   */
 }
-  else if (P-h_original == (revision_t)B) {
-/* The backup is the id object.  P becomes outdated. */
-assert(!(P-h_tid  GCFLAG_HAS_ID));
-P-h_tid |= GCFLAG_PUBLIC;
-B-h_tid |= GCFLAG_PUBLIC;
-B-h_tid = ~GCFLAG_BACKUP_COPY;
-if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
-  }
   else
 {
   /* copy the backup copy B back over the now-protected object P,
  and then free B, which will not be used any more. */
-
+  assert(!(P-h_original) 
+ || (B-h_original == (revision_t)P-h_original));
+  assert(!(P-h_original  !B-h_original));
   if (P-h_original  !B-h_original) // might occur because of
 B-h_original = P-h_original; //replace_ptr_to_protected_with_stub
 
-  assert(!(P-h_original) 
- || (B-h_original == (revision_t)P-h_original));
   size_t size = stmcb_size(B);
   assert(B-h_tid  GCFLAG_BACKUP_COPY);
   memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -159,18 +159,10 @@
  p, (gcptr)p-h_original));
 return p-h_original;
 } 
-else if (!(p-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED)
-(p-h_tid  GCFLAG_OLD)) {
-/* we can be sure that p-h_original doesn't
-   get set during the if and the else-if 
-   
-   XXX: check for priv_from_protected may not be 
-   necessary. only if this func may be called on 
-   another thread's young objects that are made 
-   old at the same time, and we see the OLD flag 
-   before h_original has been set.
-*/
-dprintf((stm_id(%p) is old, orig=0 fst: %p\n, p, p));
+else if (p-h_tid  GCFLAG_OLD) {
+/* old objects must have an h_original xOR be
+   the original itself. */
+/* dprintf((stm_id(%p) is old, orig=0 fst: %p\n, p, p)); */
 return (revision_t)p;
  

[pypy-commit] stmgc default: stm_id cleanups and fixes

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r275:d19d08d186b1
Date: 2013-06-25 15:31 +0200
http://bitbucket.org/pypy/stmgc/changeset/d19d08d186b1/

Log:stm_id cleanups and fixes

diff --git a/c4/atomic_ops.h b/c4/atomic_ops.h
--- a/c4/atomic_ops.h
+++ b/c4/atomic_ops.h
@@ -2,7 +2,7 @@
 #define _SRCSTM_ATOMIC_OPS_
 
 #include assert.h
-
+#define IMPLIES(a, b)   (!(a) || (b))
 
 /* Ask the compiler to really reload the revision_t argument from memory.
That's all that this macro does; it does not imply any type of barrier.
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1031,8 +1031,9 @@
   stub-h_tid = (L-h_tid  STM_USER_TID_MASK) | GCFLAG_PUBLIC
| GCFLAG_STUB
| GCFLAG_OLD;
+  stub-h_revision = ((revision_t)L) | 2;
+
   assert(!(L-h_tid  GCFLAG_HAS_ID));
-  stub-h_revision = ((revision_t)L) | 2;
   if (L-h_original) {
 stub-h_original = L-h_original;
   }
@@ -1040,8 +1041,14 @@
 stub-h_original = (revision_t)L;
   }
   else {
-L-h_original = (revision_t)stub;
+/* There shouldn't be a public, young object without
+   a h_original. They only come from stealing which
+   always sets h_original */
 assert(0);
+/* L-h_original = (revision_t)stub; */
+/* if (L-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) { */
+/*   ((gcptr)L-h_revision)-h_original = (revision_t)stub; */
+/* } */
   }
   
   item-val = stub;
@@ -1165,12 +1172,6 @@
 {
   /* copy the backup copy B back over the now-protected object P,
  and then free B, which will not be used any more. */
-  assert(!(P-h_original) 
- || (B-h_original == (revision_t)P-h_original));
-  assert(!(P-h_original  !B-h_original));
-  if (P-h_original  !B-h_original) // might occur because of
-B-h_original = P-h_original; //replace_ptr_to_protected_with_stub
-
   size_t size = stmcb_size(B);
   assert(B-h_tid  GCFLAG_BACKUP_COPY);
   memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -162,7 +162,7 @@
 else if (p-h_tid  GCFLAG_OLD) {
 /* old objects must have an h_original xOR be
the original itself. */
-/* dprintf((stm_id(%p) is old, orig=0 fst: %p\n, p, p)); */
+dprintf((stm_id(%p) is old, orig=0 fst: %p\n, p, p));
 return (revision_t)p;
 }
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -53,7 +53,13 @@
 stub-h_original = (revision_t)obj;
 }
 else {
-obj-h_original = (revision_t)stub;
+/* There shouldn't be a public, young object without
+   a h_original. But there can be protected ones. */
+assert(!(obj-h_tid  GCFLAG_PUBLIC));
+obj-h_original = (revision_t)stub;
+if (obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
+((gcptr)obj-h_revision)-h_original = (revision_t)stub;
+}
 }
 
 g2l_insert(sd-all_stubs, obj, stub);
@@ -93,23 +99,23 @@
 if (L-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
 gcptr B = (gcptr)L-h_revision; /* the backup copy */
 
-if (L-h_original) {
-/* L has an original, may be GCFLAG_HAS_ID */
-B-h_original = L-h_original;
-L-h_tid = ~GCFLAG_HAS_ID;
-}
-else if (L-h_tid  GCFLAG_OLD) {
-/* If old, it must be the original */
-assert(!(L-h_tid  GCFLAG_HAS_ID));
-/* original must be L */
+/* On young objects here, h_original is always set
+ and never GCFLAG_HAS_ID. This is because a stealing
+ thread can only reach a priv_from_prot object through
+ public old stubs/objects that serve as originals if
+ needed.
+ If h_original is set, then it is already set in the
+ backup, too.
+*/
+assert(!(L-h_tid  GCFLAG_HAS_ID));
+assert(IMPLIES(!(L-h_tid  GCFLAG_OLD), L-h_original));
+assert(IMPLIES(L-h_tid  GCFLAG_OLD,
+   (B-h_original == (revision_t)L) 
+   || (B-h_original == L-h_original)));
+if (!L-h_original  L-h_tid  GCFLAG_OLD) {
+/* If old, L must be the original */
 B-h_original = (revision_t)L;
 }
-else {
-/* we can make the backup the original
- since L hasn't decided yet */
-L-h_original = (revision_t)B;
-assert(0);
-}
 
 /* B is now a backup copy, i.e. a protected object, and we own
the foreign thread's collection_lock, so we can read/write the
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
@@ -539,6 +539,7 

[pypy-commit] stmgc default: clean only used part of nursery

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r279:0f3222c773e9
Date: 2013-06-25 16:51 +0200
http://bitbucket.org/pypy/stmgc/changeset/0f3222c773e9/

Log:clean only used part of nursery

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -516,7 +516,8 @@
 dprintf((minor: nursery moved to [%p to %p]\n, d-nursery_base,
  d-nursery_end));
 #else
-memset(d-nursery_base, 0, GC_NURSERY);
+memset(d-nursery_base, 0,
+   d-nursery_current - d-nursery_base);
 #endif
 d-nursery_current = d-nursery_base;
 
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -3,6 +3,7 @@
 
 #ifndef GC_NURSERY
 #define GC_NURSERY4194304/* 4 MB */
+//#define GC_NURSERY(120)/* 1 MB */
 #endif
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: fix validation of priv_from_prot

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r283:2e4480dc9707
Date: 2013-06-25 17:51 +0200
http://bitbucket.org/pypy/stmgc/changeset/2e4480dc9707/

Log:fix validation of priv_from_prot

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -330,6 +330,14 @@
 p = (gcptr)(((nodeptr)read_barrier(p))-next);
 break;
 case 9: // XXX: rare events
+k = get_rand(10);
+if (k == 1) {
+push_roots();
+stm_push_root(p);
+stm_become_inevitable(fun);
+p = stm_pop_root();
+pop_roots();
+}
 break;
 case 10: // only do a stm_read_barrier
 p = read_barrier(p);
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -652,12 +652,17 @@
 {
   /* such an object R might be listed in list_of_read_objects
  before it was turned from protected to private */
-  continue;
+  if(((gcptr)v)-h_tid  GCFLAG_BACKUP_COPY)
+continue;
+  /* the backup was stolen */
+  return 0; 
 }
   else if ((R-h_tid  (GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED))
 == (GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED))
 {
-  /* such an object is identical to the one it points to */
+  /* such an object is identical to the one it points to
+   (stolen protected young object with h_revision pointing
+   to the new copy) */
   R = (gcptr)v;
   goto retry;
 }
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: break the huge switch in demo_random

2013-06-25 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r284:7b5404748520
Date: 2013-06-25 18:15 +0200
http://bitbucket.org/pypy/stmgc/changeset/7b5404748520/

Log:break the huge switch 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
@@ -274,93 +274,97 @@
 
 }
 
-gcptr do_step(gcptr p)
+gcptr rare_events(gcptr p, gcptr _r, gcptr _sr)
 {
-nodeptr w_r, w_sr, w_t;
-gcptr _r, _sr, _t;
-int num, k;
+int k = get_rand(10);
+if (k == 1) {
+push_roots();
+stm_push_root(p);
+stm_become_inevitable(fun);
+p = stm_pop_root();
+pop_roots();
+} 
+else if (k  4) {
+push_roots();
+stmgc_minor_collect();
+pop_roots();
+p = NULL;
+}
+return p;
+}
 
-_t = NULL;
-num = get_rand(td.num_roots);
-_r = td.roots[num];
-
-num = get_rand(SHARED_ROOTS);
-_sr = shared_roots[num];
-
-k = get_rand(19);
-check(p);
-
+gcptr simple_events(gcptr p, gcptr _r, gcptr _sr)
+{
+nodeptr w_r;
+int k = get_rand(8);
+int num = get_rand(td.num_roots);
 switch (k) {
 case 0: // remove a root
 if (num  0)
 del_root(num);
 break;
-case 1: // set 'p' to point to a root
+case 1: // add 'p' to roots
+if (p  td.num_roots  MAXROOTS)
+td.roots[td.num_roots++] = p;
+break;
+case 2: // set 'p' to point to a root
 if (_r)
 p = _r;
 break;
-case 2: // add 'p' to roots
-if (p  td.num_roots  MAXROOTS)
-td.roots[td.num_roots++] = p;
-break;
 case 3: // allocate fresh 'p'
 p = (gcptr)allocate_node();
 break;
-case 4: // set 'p' as *next in one of the roots
+case 4:  // read and validate 'p'
+p = read_barrier(p);
+break;
+case 5: // only do a stm_write_barrier
+p = write_barrier(p);
+break;
+case 6: // follow p-next
+if (p)
+p = (gcptr)(((nodeptr)read_barrier(p))-next);
+break;
+case 7: // set 'p' as *next in one of the roots
 check(_r);
 w_r = (nodeptr)write_barrier(_r);
 check((gcptr)w_r);
 check(p);
 w_r-next = (struct node*)p;
 break;
-case 5:  // read and validate 'p'
-read_barrier(p);
-break;
-case 6: // transaction break
-if (td.interruptible)
-return (gcptr)-1; // break current
-transaction_break();
-p = NULL;
-break;
-case 7: // only do a stm_write_barrier
-p = write_barrier(p);
-break;
-case 8:
-if (p)
-p = (gcptr)(((nodeptr)read_barrier(p))-next);
-break;
-case 9: // XXX: rare events
-k = get_rand(10);
-if (k == 1) {
-push_roots();
-stm_push_root(p);
-stm_become_inevitable(fun);
-p = stm_pop_root();
-pop_roots();
-}
-break;
-case 10: // only do a stm_read_barrier
-p = read_barrier(p);
-break;
-case 11:
+}
+return p;
+}
+
+gcptr shared_roots_events(gcptr p, gcptr _r, gcptr _sr)
+{
+nodeptr w_sr;
+
+int k = get_rand(3);
+switch (k) {
+case 0: // read_barrier on shared root
 read_barrier(_sr);
 break;
-case 12:
+case 1: // write_barrier on shared root
 write_barrier(_sr);
 break;
-case 13:
+case 2:
 w_sr = (nodeptr)write_barrier(_sr);
 w_sr-next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)];
 break;
-case 14:
-push_roots();
-stmgc_minor_collect();
-pop_roots();
-p = NULL;
-break;
-case 15: /* test stm_id on (non-)shared roots */
+}
+return p;
+}
+
+gcptr id_hash_events(gcptr p, gcptr _r, gcptr _sr)
+{
+nodeptr w_t;
+int k = get_rand(4);
+gcptr _t = NULL;
+
+switch (k) {
+case 0: /* test stm_id on (non-)shared roots */
 _t = _r;
-case 16:
+case 1:
 if (!_t)
 _t = _sr;
 w_t = (nodeptr)read_barrier(_t);
@@ -374,9 +378,9 @@
 assert(w_t-id == stm_id((gcptr)_t));
 }
 break;
-case 17: /* test stm_hash on (non-)shared roots */
+case 2: /* test stm_hash on (non-)shared roots */
 _t = _r;
-case 18:
+case 3:
 if (!_t)
 _t = _sr;
 w_t = (nodeptr)read_barrier(_t);
@@ -400,6 +404,40 @@
 }
 
 
+
+gcptr do_step(gcptr p)
+{
+gcptr _r, _sr;
+int num, k;
+
+num = get_rand(td.num_roots);
+_r = td.roots[num];
+
+num = get_rand(SHARED_ROOTS);
+_sr = shared_roots[num];
+
+k = get_rand(9);
+check(p);
+
+if (k  3)
+p = simple_events(p, _r, _sr);
+else if (k  5)
+p = shared_roots_events(p, _r, _sr);
+else if (k  7)
+p = id_hash_events(p, _r, _sr);
+else if (k  8)
+p = 

[pypy-commit] stmgc default: add major collections to test

2013-07-01 Thread Raemi
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] stmgc default: fix uninitialized shadowstack problem during major collection

2013-07-01 Thread Raemi
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 atomic transactions in demo_random

2013-07-01 Thread Raemi
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: add build and release versions of demo_random to tests

2013-07-01 Thread Raemi
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


[pypy-commit] stmgc default: this assert can fail

2013-07-02 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r338:2040cea49c77
Date: 2013-07-02 12:23 +0200
http://bitbucket.org/pypy/stmgc/changeset/2040cea49c77/

Log:this assert can fail

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -44,7 +44,11 @@
 void stmgc_done_nursery(void)
 {
 struct tx_descriptor *d = thread_descriptor;
-assert(!minor_collect_anything_to_do(d));
+/* someone may have called minor_collect_soon()
+   inbetween the preceeding minor_collect() and 
+   this assert (committransaction() - 
+   updatechainheads() - stub_malloc() - ...): */
+/* assert(!minor_collect_anything_to_do(d)); */
 stm_free(d-nursery_base, GC_NURSERY);
 
 gcptrlist_delete(d-old_objects_to_trace);
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add stm_thread_local_obj to demo_random.c

2013-07-03 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r339:e7d1df97b6f0
Date: 2013-07-03 09:54 +0200
http://bitbucket.org/pypy/stmgc/changeset/e7d1df97b6f0/

Log:add stm_thread_local_obj to demo_random.c

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -293,6 +293,20 @@
 td.roots[i] = (gcptr)allocate_node();
 }
 
+if (td.thread_seed % 3 == 0) {
+stm_thread_local_obj = (gcptr)allocate_node();
+}
+else if (td.thread_seed % 3 == 1) {
+stm_thread_local_obj = allocate_pseudoprebuilt_with_hash
+(
+ sizeof(struct node), GCTID_STRUCT_NODE, PREBUILT);
+((nodeptr)stm_thread_local_obj)-hash = PREBUILT;
+} 
+else {
+stm_thread_local_obj = allocate_pseudoprebuilt
+(sizeof(struct node), GCTID_STRUCT_NODE);
+}
+
 }
 
 gcptr rare_events(gcptr p, gcptr _r, gcptr _sr)
@@ -432,7 +446,7 @@
 w_t-hash = stm_hash((gcptr)w_t);
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
-if (w_t-hash = 0  (w_t-hash  PREBUILT ||
+if (w_t-hash = 0  (w_t-hash = PREBUILT ||
w_t-hash  SHARED_ROOTS)) {
 // should be with predefined hash
 assert (stm_id((gcptr)w_t) != stm_hash((gcptr)w_t));
@@ -449,8 +463,11 @@
 gcptr _r, _sr;
 int num, k;
 
-num = get_rand(td.num_roots);
-_r = td.roots[num];
+num = get_rand(td.num_roots+1);
+if (num == 0)
+_r = stm_thread_local_obj;
+else
+_r = td.roots[num - 1];
 
 num = get_rand(SHARED_ROOTS);
 _sr = shared_roots[num];
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: add _GC_DEBUGPRINTS, comments, and some fairly untested code about tracing h_original in major_collections

2013-07-03 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r344:f37e2b89a0fc
Date: 2013-07-03 17:03 +0200
http://bitbucket.org/pypy/stmgc/changeset/f37e2b89a0fc/

Log:add _GC_DEBUGPRINTS, comments, and some fairly untested code about
tracing h_original in major_collections

diff --git a/c4/Makefile b/c4/Makefile
--- a/c4/Makefile
+++ b/c4/Makefile
@@ -21,15 +21,16 @@
 C_FILES = et.c lists.c steal.c nursery.c gcpage.c \
   stmsync.c dbgmem.c fprintcolor.c
 
-DEBUG = -g -DGC_NURSERY=0x1 -D_GC_DEBUG=1
+DEBUG = -g -DGC_NURSERY=0x1 -D_GC_DEBUG=1 -DDUMP_EXTRA=1 
-D_GC_DEBUGPRINTS=1
 
 
-# note that we don't say -DNDEBUG, so that asserts should still be compiled it
+# note that we don't say -DNDEBUG, so that asserts should still be compiled in
+# also, all debug code with extra checks but not the debugprints
 build-%: %.c ${H_FILES} ${C_FILES} stmgc.c
-   gcc  -pthread -O2 -g $ -o build-$* -Wall stmgc.c -lrt
+   gcc -pthread -DGC_NURSERY=0x1  -D_GC_DEBUG=1 -g $ -o build-$* 
-Wall stmgc.c -lrt
 
 debug-%: %.c ${H_FILES} ${C_FILES}
-   gcc -pthread ${DEBUG} $ -o debug-$* -Wall ${C_FILES} -lrt
+   gcc -pthread -DDUMP_EXTRA=1 ${DEBUG} $ -o debug-$* -Wall ${C_FILES} 
-lrt
 
 release-%: %.c ${H_FILES} ${C_FILES} stmgc.c
gcc -pthread -DNDEBUG -O2 -g $ -o release-$* -Wall stmgc.c -lrt
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -105,6 +105,15 @@
 *(to++) = *(from++);
 }
 
+gcptr allocate_old(size_t size, int tid)
+{
+gcptr p = stmgcpage_malloc(size);
+memset(p, 0, size);
+p-h_tid = GCFLAG_OLD | GCFLAG_WRITE_BARRIER | tid;
+p-h_revision = -INT_MAX;
+return p;
+}
+
 gcptr allocate_pseudoprebuilt(size_t size, int tid)
 {
 gcptr x = calloc(1, size);
@@ -166,6 +175,15 @@
 return 0;
 }
 
+#ifdef _GC_DEBUG
+int is_free_old(gcptr p)
+{
+fprintf(stdout, \n=== check ===\n);
+return (!_stm_can_access_memory((char*)p))
+|| (p-h_tid == DEBUG_WORD(0xDD));
+}
+#endif
+
 void check_not_free(gcptr p)
 {
 assert(p != NULL);
@@ -179,6 +197,16 @@
 if (p != NULL) {
 check_not_free(p);
 classify(p); // additional asserts
+if (p-h_original  !(p-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
+// must point to valid old object
+gcptr id = (gcptr)p-h_original;
+assert(id-h_tid  GCFLAG_OLD);
+check_not_free(id);
+#ifdef _GC_DEBUG
+if (!is_shared_prebuilt(id)  !(id-h_tid  GCFLAG_PREBUILT))
+assert(!is_free_old(id));
+#endif
+}
 }
 }
 
diff --git a/c4/fprintcolor.c b/c4/fprintcolor.c
--- a/c4/fprintcolor.c
+++ b/c4/fprintcolor.c
@@ -5,7 +5,7 @@
 {
 va_list ap;
 
-#ifdef _GC_DEBUG
+#ifdef _GC_DEBUGPRINTS
 dprintf((STM Subsystem: Fatal Error\n));
 #else
 fprintf(stderr, STM Subsystem: Fatal Error\n);
@@ -19,7 +19,7 @@
 }
 
 
-#ifdef _GC_DEBUG
+#ifdef _GC_DEBUGPRINTS
 
 static __thread revision_t tcolor = 0;
 static revision_t tnextid = 0;
diff --git a/c4/fprintcolor.h b/c4/fprintcolor.h
--- a/c4/fprintcolor.h
+++ b/c4/fprintcolor.h
@@ -6,7 +6,7 @@
  __attribute__((format (printf, 1, 2), noreturn));
 
 
-#ifdef _GC_DEBUG
+#ifdef _GC_DEBUGPRINTS
 
 #define dprintf(args)   threadcolor_printf args
 int dprintfcolor(void);
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -235,6 +235,15 @@
 if (!(obj-h_revision  2)) {
 /* go visit the more recent version */
 obj = (gcptr)obj-h_revision;
+if ((gcptr)obj-h_original == prev_obj
+ !(prev_obj-h_tid  GCFLAG_VISITED)) {
+assert(0); // why never hit?
+// prev_obj is the ID copy
+prev_obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
+/* see fix_outdated() */
+prev_obj-h_tid |= GCFLAG_VISITED;
+gcptrlist_insert(objects_to_trace, prev_obj);
+}
 }
 else {
 /* it's a stub: keep it if it points to a protected version,
@@ -244,7 +253,11 @@
 */
 assert(obj-h_tid  GCFLAG_STUB);
 obj = (gcptr)(obj-h_revision - 2);
-if (!(obj-h_tid  GCFLAG_PUBLIC)) {
+if (!(obj-h_tid  GCFLAG_PUBLIC) || !(prev_obj-h_original)) {
+assert(prev_obj-h_original); // why never hit?
+assert(!(obj-h_tid  GCFLAG_PUBLIC));
+/* never?: stub-public where stub is id copy? */
+
 prev_obj-h_tid |= GCFLAG_VISITED;
 assert(*pobj == prev_obj);
 gcptr obj1 = obj;
@@ -256,6 +269,9 @@
 }
 
 if (!(obj-h_revision  3)) {
+/* obj is neither a stub nor a most recent revision:
+   completely ignore obj-h_revision */
+
 obj = (gcptr)obj-h_revision;
 assert(obj-h_tid  GCFLAG_PUBLIC);
 prev_obj-h_revision = (revision_t)obj;
@@ -274,7 +290,21 @@
   

[pypy-commit] stmgc default: add test and fix

2013-07-04 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r346:38fcfb8212e2
Date: 2013-07-04 10:27 +0200
http://bitbucket.org/pypy/stmgc/changeset/38fcfb8212e2/

Log:add test and fix

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -220,6 +220,11 @@
hash in h_original */
 if (id_copy  !(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
 if (!(id_copy-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
+id_copy-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
+/* see fix_outdated() */
+id_copy-h_tid |= GCFLAG_VISITED;
+
+/* XXX: may not always need tracing? */
 gcptrlist_insert(objects_to_trace, id_copy);
 } 
 else {
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -298,6 +298,8 @@
  undef_macros=['NDEBUG'],
  define_macros=[('GC_NURSERY', str(16 * WORD)),
 ('_GC_DEBUG', '2'),
+('_GC_DEBUGPRINTS', '1'),
+('DUMP_EXTRA', '1'),
 ('GC_PAGE_SIZE', '1000'),
 ('GC_MIN', '20'),
 ('GC_EXPAND', '9'),
@@ -576,6 +578,13 @@
 if p1.h_tid  GCFLAG_PREBUILT_ORIGINAL:
 lib.stm_add_prebuilt_root(p1)
 
+def delegate_original(p1, p2):
+assert p1.h_original == 0
+assert p2.h_original == 0
+assert p1 != p2
+p2.h_original = ffi.cast(revision_t, p1)
+
+
 def make_public(p1):
 Hack at an object returned by oalloc() to force it public.
 assert classify(p1) == protected
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -200,6 +200,20 @@
 assert p3 != p2
 assert p3 == lib.stm_write_barrier(p2)
 
+def test_new_version_id_alive():
+p1 = oalloc(HDR); make_public(p1)
+p2 = oalloc(HDR); make_public(p2)
+delegate(p1, p2)
+delegate_original(p1, p2)
+p2.h_original = ffi.cast(revision_t, p1)
+lib.stm_push_root(p1)
+major_collect()
+major_collect()
+p1b = lib.stm_pop_root()
+check_not_free(p1) # id copy
+check_not_free(p2)
+
+
 def test_new_version_kill_intermediate():
 p1 = oalloc(HDR); make_public(p1)
 p2 = oalloc(HDR); make_public(p2)
@@ -249,6 +263,34 @@
 print 'p5:', p5
 assert rawgetptr(p1, 0) == p5
 
+def test_new_version_not_kill_intermediate_original():
+p1 = oalloc_refs(1); make_public(p1)
+p2 = oalloc(HDR);make_public(p2)
+p3 = oalloc(HDR);make_public(p3)
+p4 = oalloc(HDR);make_public(p4)
+p5 = oalloc(HDR);make_public(p5)
+delegate(p2, p3)
+delegate(p3, p4)
+delegate(p4, p5)
+rawsetptr(p1, 0, p3)
+delegate_original(p3, p1)
+delegate_original(p3, p2)
+delegate_original(p3, p4)
+delegate_original(p3, p5)
+
+lib.stm_push_root(p1)
+major_collect()
+lib.stm_pop_root()
+check_not_free(p1)
+check_free_old(p2)
+check_not_free(p3) # original
+check_free_old(p4)
+check_not_free(p5)
+assert rawgetptr(p1, 0) == p5
+assert follow_original(p1) == p3
+assert follow_original(p5) == p3
+
+
 def test_prebuilt_version_1():
 p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
 check_prebuilt(p1)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: refactor keeping alive the h_originals in major collections

2013-07-04 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r345:7ae6aa7d16af
Date: 2013-07-04 09:26 +0200
http://bitbucket.org/pypy/stmgc/changeset/7ae6aa7d16af/

Log:refactor keeping alive the h_originals in major collections

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -212,6 +212,24 @@
 
 static struct GcPtrList objects_to_trace;
 
+static void keep_original_alive(gcptr obj)
+{
+/* keep alive the original of a visited object */
+gcptr id_copy = (gcptr)obj-h_original;
+/* prebuilt original objects may have a predifined
+   hash in h_original */
+if (id_copy  !(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
+if (!(id_copy-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
+gcptrlist_insert(objects_to_trace, id_copy);
+} 
+else {
+/* prebuilt originals won't get collected anyway
+   and if they are not reachable in any other way,
+   we only ever need their location, not their content */
+}
+}
+}
+
 static void visit(gcptr *pobj)
 {
 gcptr obj = *pobj;
@@ -226,6 +244,8 @@
 obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;  /* see fix_outdated() */
 obj-h_tid |= GCFLAG_VISITED;
 gcptrlist_insert(objects_to_trace, obj);
+
+keep_original_alive(obj);
 }
 }
 else if (obj-h_tid  GCFLAG_PUBLIC) {
@@ -235,15 +255,6 @@
 if (!(obj-h_revision  2)) {
 /* go visit the more recent version */
 obj = (gcptr)obj-h_revision;
-if ((gcptr)obj-h_original == prev_obj
- !(prev_obj-h_tid  GCFLAG_VISITED)) {
-assert(0); // why never hit?
-// prev_obj is the ID copy
-prev_obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
-/* see fix_outdated() */
-prev_obj-h_tid |= GCFLAG_VISITED;
-gcptrlist_insert(objects_to_trace, prev_obj);
-}
 }
 else {
 /* it's a stub: keep it if it points to a protected version,
@@ -253,12 +264,10 @@
 */
 assert(obj-h_tid  GCFLAG_STUB);
 obj = (gcptr)(obj-h_revision - 2);
-if (!(obj-h_tid  GCFLAG_PUBLIC) || !(prev_obj-h_original)) {
-assert(prev_obj-h_original); // why never hit?
-assert(!(obj-h_tid  GCFLAG_PUBLIC));
-/* never?: stub-public where stub is id copy? */
+if (!(obj-h_tid  GCFLAG_PUBLIC)) {
+prev_obj-h_tid |= GCFLAG_VISITED;
+keep_original_alive(prev_obj);
 
-prev_obj-h_tid |= GCFLAG_VISITED;
 assert(*pobj == prev_obj);
 gcptr obj1 = obj;
 visit(obj1);   /* recursion, but should be only once */
@@ -291,18 +300,11 @@
 gcptr B = (gcptr)obj-h_revision;
 assert(B-h_tid  (GCFLAG_PUBLIC | GCFLAG_BACKUP_COPY));
 
-gcptr id_copy = (gcptr)obj-h_original;
-if (id_copy  id_copy != B) {
-assert(id_copy == (gcptr)B-h_original);
+if (obj-h_original  (gcptr)obj-h_original != B) {
+/* if B is original, it will be visited anyway */
+assert(obj-h_original == B-h_original);
 assert(!(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL));
-if (!(id_copy-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
-gcptrlist_insert(objects_to_trace, id_copy);
-} 
-else {
-/* prebuilt originals won't get collected anyway
- and if they are not reachable in any other way,
- we only ever need their location, not their content */
-}
+keep_original_alive(obj);
 }
 
 obj-h_tid |= GCFLAG_VISITED;
@@ -323,6 +325,7 @@
 }
 }
 
+
 static void visit_keep(gcptr obj)
 {
 if (!(obj-h_tid  GCFLAG_VISITED)) {
@@ -334,6 +337,7 @@
 assert(!(obj-h_revision  2));
 visit((gcptr *)obj-h_revision);
 }
+keep_original_alive(obj);
 }
 }
 
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -266,7 +266,7 @@
 return fresh_old_copy;
 }
 
-inline void copy_to_old_id_copy(gcptr obj, gcptr id)
+void copy_to_old_id_copy(gcptr obj, gcptr id)
 {
 assert(!is_in_nursery(thread_descriptor, id));
 assert(id-h_tid  GCFLAG_OLD);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -1,7 +1,7 @@
 #include stmimpl.h
 
 
-inline void copy_to_old_id_copy(gcptr obj, gcptr id);
+void copy_to_old_id_copy(gcptr obj, gcptr id);
 
 gcptr stm_stub_malloc(struct tx_public_descriptor *pd)
 {
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: merge

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r350:93309df73f62
Date: 2013-07-05 09:46 +0200
http://bitbucket.org/pypy/stmgc/changeset/93309df73f62/

Log:merge

diff --git a/duhton/duhton.c b/duhton/duhton.c
--- a/duhton/duhton.c
+++ b/duhton/duhton.c
@@ -1,20 +1,40 @@
 #include duhton.h
 
+#define DEFAULT_NUM_THREADS 4
 
 int main(int argc, char **argv)
 {
-char *filename;
-int interactive;
-if (argc = 1) {
+char *filename = NULL;
+int interactive = 1;
+   int i;
+   int num_threads = DEFAULT_NUM_THREADS;
+
+   for (i = 1; i  argc; ++i) {
+   if (strcmp(argv[i], --help) == 0) {
+   printf(Duhton: a simple lisp-like language with STM 
support\n\n);
+   printf(Usage: duhton [--help] [--num-threads no] 
[filename]\n);
+   printf(  --help: this help\n);
+   printf(  --num-threads number: number of threads 
(default 4)\n\n);
+   exit(0);
+   } else if (strcmp(argv[i], --num-threads) == 0) {
+   if (i == argc - 1) {
+   printf(ERROR: --num-threads requires a 
parameter\n);
+   exit(1);
+   }
+   num_threads = atoi(argv[i + 1]);
+   i++;
+   } else if (strncmp(argv[i], --, 2) == 0) {
+   printf(ERROR: unrecognized parameter %s\n, argv[i]);
+   } else {
+   filename = argv[i];
+   interactive = 0;
+   }
+   }
+if (!filename) {
 filename = -;   /* stdin */
-interactive = 1;
-}
-else {
-filename = argv[1];
-interactive = 0;
-}
+   }
 
-Du_Initialize();
+Du_Initialize(num_threads);
 
 while (1) {
 if (interactive) {
diff --git a/duhton/duhton.h b/duhton/duhton.h
--- a/duhton/duhton.h
+++ b/duhton/duhton.h
@@ -138,7 +138,7 @@
 DuObject *rest, int execute_now);
 DuObject *_Du_GetGlobals(void);
 
-void Du_Initialize(void);
+void Du_Initialize(int);
 void Du_Finalize(void);
 #define Du_Globals(_Du_GetGlobals())
 
@@ -182,5 +182,7 @@
 }
 #endif
 
+extern pthread_t *all_threads;
+extern int all_threads_count;
 
 #endif  /* _DUHTON_H_ */
diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -1,6 +1,8 @@
 #include duhton.h
 #include sys/select.h
 
+pthread_t *all_threads;
+int all_threads_count;
 
 static void _du_getargs1(const char *name, DuObject *cons, DuObject *locals,
  DuObject **a)
@@ -561,9 +563,11 @@
 return Du_None;
 }
 
-void Du_Initialize(void)
+void Du_Initialize(int num_threads)
 {
 stm_initialize();
+   all_threads_count = num_threads;
+   all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads);
 
 DuFrame_SetBuiltinMacro(Du_Globals, progn, Du_Progn);
 DuFrame_SetBuiltinMacro(Du_Globals, setq, du_setq);
diff --git a/duhton/transaction.c b/duhton/transaction.c
--- a/duhton/transaction.c
+++ b/duhton/transaction.c
@@ -2,10 +2,6 @@
 #include pthread.h
 #include unistd.h
 
-#ifndef NUM_THREADS
-#define NUM_THREADS  4
-#endif
-
 
 static DuConsObject du_pending_transactions = {
 DuOBJECT_HEAD_INIT(DUTYPE_CONS),
@@ -21,15 +17,13 @@
 static void run_all_threads(void)
 {
 int i;
-pthread_t th[NUM_THREADS];
-
-for (i = 0; i  NUM_THREADS; i++) {
-int status = pthread_create(th[i], NULL, run_thread, NULL);
+for (i = 0; i  all_threads_count; i++) {
+int status = pthread_create(all_threads[i], NULL, run_thread, NULL);
 if (status != 0)
 stm_fatalerror(status != 0\n);
 }
-for (i = 0; i  NUM_THREADS; i++) {
-pthread_join(th[i], NULL);
+for (i = 0; i  all_threads_count; i++) {
+pthread_join(all_threads[i], NULL);
 }
 }
 
@@ -88,13 +82,13 @@
 else {
 /* nothing to do, wait */
 thread_sleeping++;
-if (thread_sleeping == NUM_THREADS) {
+if (thread_sleeping == all_threads_count) {
 pthread_mutex_unlock(mutex_sleep);
 }
 stm_commit_transaction();
 pthread_mutex_lock(mutex_sleep);
 stm_begin_inevitable_transaction();
-if (thread_sleeping == NUM_THREADS) {
+if (thread_sleeping == all_threads_count) {
 pthread_mutex_unlock(mutex_sleep);
 return NULL;
 }
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: fix: don't trace stubs

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r349:de365b519570
Date: 2013-07-05 09:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/de365b519570/

Log:fix: don't trace stubs

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -225,7 +225,8 @@
 id_copy-h_tid |= GCFLAG_VISITED;
 
 /* XXX: may not always need tracing? */
-gcptrlist_insert(objects_to_trace, id_copy);
+if (!(id_copy-h_tid  GCFLAG_STUB))
+gcptrlist_insert(objects_to_trace, id_copy);
 } 
 else {
 /* prebuilt originals won't get collected anyway
diff --git a/duhton/Makefile b/duhton/Makefile
--- a/duhton/Makefile
+++ b/duhton/Makefile
@@ -5,7 +5,7 @@
gcc -pthread -g -O2 -o duhton *.c ../c4/stmgc.c -Wall -lrt 
 
 duhton_debug: *.c *.h ../c4/*.c ../c4/*.h
-   gcc -pthread -g -DDu_DEBUG -D_GC_DEBUG=2 -DGC_NURSERY=2048 -o 
duhton_debug *.c ../c4/stmgc.c -Wall -lrt 
+   gcc -pthread -g -DDu_DEBUG -D_GC_DEBUGPRINTS=1 -DGC_NURSERY=2048 -o 
duhton_debug *.c ../c4/stmgc.c -Wall -lrt 
 
 clean:
rm -f duhton duhton_debug
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: fix some tests

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65190:b3adf69b07ae
Date: 2013-07-05 10:46 +0200
http://bitbucket.org/pypy/pypy/changeset/b3adf69b07ae/

Log:fix some tests

diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py
--- a/pypy/module/thread/stm.py
+++ b/pypy/module/thread/stm.py
@@ -5,7 +5,7 @@
 from pypy.module.thread.threadlocals import BaseThreadLocals
 from pypy.module.thread.error import wrap_thread_error
 from pypy.interpreter.executioncontext import ExecutionContext
-from pypy.interpreter.gateway import Wrappable, W_Root, interp2app
+from pypy.interpreter.gateway import W_Root, interp2app
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, descr_get_dict
 from rpython.rlib import rthread
 from rpython.rlib import rstm
@@ -122,7 +122,7 @@
 # 
 
 
-class STMLocal(Wrappable):
+class STMLocal(W_Root):
 Thread-local data
 
 @jit.dont_look_inside
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -28,13 +28,13 @@
 
 def abort_info_pop(count):
 if we_are_translated():
-stmgcintf.StmOperations.abort_info_pop(count)
+pass #stmgcintf.StmOperations.abort_info_pop(count)
 
 def charp_inspect_abort_info():
-return stmgcintf.StmOperations.inspect_abort_info()
+pass # return stmgcintf.StmOperations.inspect_abort_info()
 
 def abort_and_retry():
-stmgcintf.StmOperations.abort_and_retry()
+pass # stmgcintf.StmOperations.abort_and_retry()
 
 def before_external_call():
 llop.stm_commit_transaction(lltype.Void)
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
@@ -584,28 +584,30 @@
 from rpython.translator.stm.funcgen import op_stm
 self.__class__.op_stm = op_stm
 return self.op_stm(op)
-OP_STM_INITIALIZE = _OP_STM
-OP_STM_FINALIZE = _OP_STM
-OP_STM_BECOME_INEVITABLE = _OP_STM
-OP_STM_BARRIER = _OP_STM
-OP_STM_PTR_EQ = _OP_STM
-OP_STM_PUSH_ROOT = _OP_STM
-OP_STM_POP_ROOT_INTO = _OP_STM
-OP_STM_ALLOCATE = _OP_STM
-OP_STM_GET_TID = _OP_STM
-OP_STM_HASH = _OP_STM
-OP_STM_ID = _OP_STM
-OP_STM_COMMIT_TRANSACTION = _OP_STM
+OP_STM_INITIALIZE   = _OP_STM
+OP_STM_FINALIZE = _OP_STM
+OP_STM_BECOME_INEVITABLE= _OP_STM
+OP_STM_BARRIER  = _OP_STM
+OP_STM_PTR_EQ   = _OP_STM
+OP_STM_PUSH_ROOT= _OP_STM
+OP_STM_POP_ROOT_INTO= _OP_STM
+OP_STM_ALLOCATE = _OP_STM
+OP_STM_GET_TID  = _OP_STM
+OP_STM_HASH = _OP_STM
+OP_STM_ID   = _OP_STM
+OP_STM_COMMIT_TRANSACTION   = _OP_STM
 OP_STM_BEGIN_INEVITABLE_TRANSACTION = _OP_STM
-OP_STM_SHOULD_BREAK_TRANSACTION = _OP_STM
-OP_STM_SET_TRANSACTION_LENGTH = _OP_STM
-OP_STM_CHANGE_ATOMIC = _OP_STM
-OP_STM_GET_ATOMIC = _OP_STM
-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
+OP_STM_SHOULD_BREAK_TRANSACTION = _OP_STM
+OP_STM_SET_TRANSACTION_LENGTH   = _OP_STM
+OP_STM_CHANGE_ATOMIC= _OP_STM
+OP_STM_GET_ATOMIC   = _OP_STM
+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
+OP_STM_MAJOR_COLLECT= _OP_STM
+OP_STM_MINOR_COLLECT= _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
@@ -159,6 +159,13 @@
 arg0 = funcgen.expr(op.args[0])
 return 'stm_leave_callback_call(%s);' % (arg0,)
 
+def stm_minor_collect(funcgen, op):
+return 'stmgc_minor_collect();'
+
+def stm_major_collect(funcgen, op):
+return 'stmgcpage_possibly_major_collect(1);}' # forced
+
+
 
 def op_stm(funcgen, op):
 func = globals()[op.opname]
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
@@ -226,7 +226,8 @@
 id_copy-h_tid |= GCFLAG_VISITED;
 
 /* XXX: may not always need tracing? */
-gcptrlist_insert(objects_to_trace, id_copy);
+if (!(id_copy-h_tid  GCFLAG_STUB))
+gcptrlist_insert(objects_to_trace, id_copy);
 } 
  

[pypy-commit] pypy stmgc-c4: fix test

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65188:3f384e7615a0
Date: 2013-07-04 11:10 +0200
http://bitbucket.org/pypy/pypy/changeset/3f384e7615a0/

Log:fix test

diff --git a/rpython/translator/stm/test/test_inevitable.py 
b/rpython/translator/stm/test/test_inevitable.py
--- a/rpython/translator/stm/test/test_inevitable.py
+++ b/rpython/translator/stm/test/test_inevitable.py
@@ -160,7 +160,7 @@
 extfunc()
 
 res = self.interpret_inevitable(f1, [])
-assert res == 'direct_call'
+assert res == 'extfunc()'
 
 def test_rpy_direct_call(self):
 def f2():
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: getting tests to run with questionable methods

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65189:4820d8ea75ff
Date: 2013-07-05 08:20 +0200
http://bitbucket.org/pypy/pypy/changeset/4820d8ea75ff/

Log:getting tests to run with questionable methods

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -493,11 +493,11 @@
 def _setup_barriers_for_stm(self):
 from rpython.memory.gc import stmgc
 WBDescr = WriteBarrierDescr
-self.P2Rdescr = WBDescr(self, (stmgc.GCFLAG_GLOBAL,  'P2R',
+self.P2Rdescr = WBDescr(self, (0,  'P2R',
'stm_DirectReadBarrier'))
-self.P2Wdescr = WBDescr(self, (stmgc.GCFLAG_NOT_WRITTEN, 'P2W',
+self.P2Wdescr = WBDescr(self, (0, 'P2W',
'stm_WriteBarrier'))
-self.R2Wdescr = WBDescr(self, (stmgc.GCFLAG_NOT_WRITTEN, 'R2W',
+self.R2Wdescr = WBDescr(self, (0, 'R2W',
'stm_WriteBarrierFromReady'))
 self.write_barrier_descr = wbdescr: do not use
 #
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -35,6 +35,7 @@
 tdescr = get_size_descr(self.gc_ll_descr, T)
 tdescr.tid = 5678
 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
+tydescr = get_field_descr(self.gc_ll_descr, T, 'y')
 #
 A = lltype.GcArray(lltype.Signed)
 adescr = get_array_descr(self.gc_ll_descr, A)
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -1,8 +1,9 @@
 from rpython.jit.backend.llsupport.descr import *
 from rpython.jit.backend.llsupport.gc import *
 from rpython.jit.metainterp.gc import get_description
-from rpython.jit.backend.llsupport.test.test_rewrite import RewriteTests
-
+from rpython.jit.backend.llsupport.test.test_rewrite import (
+RewriteTests, BaseFakeCPU)
+from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
 
 class TestStm(RewriteTests):
 def setup_method(self, meth):
@@ -17,11 +18,12 @@
 self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
really_not_translated=True)
 #
-class FakeCPU(object):
+class FakeCPU(BaseFakeCPU):
 def sizeof(self, STRUCT):
 descr = SizeDescrWithVTable(104)
 descr.tid = 9315
 return descr
+
 self.cpu = FakeCPU()
 
 def check_rewrite(self, frm_operations, to_operations, **namespace):
@@ -48,6 +50,8 @@
 )
 
 def test_rewrite_setfield_gc_const(self):
+TP = lltype.GcArray(lltype.Signed)
+NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP))
 self.check_rewrite(
 [p1, p2]
 setfield_gc(ConstPtr(t), p2, descr=tzdescr)
@@ -58,7 +62,7 @@
 cond_call_gc_wb(p3, 0, descr=P2Wdescr)
 setfield_gc(p3, p2, descr=tzdescr)
 jump()
-)
+, t=NULL)
 
 def test_rewrite_setfield_gc_on_local(self):
 self.check_rewrite(
@@ -164,6 +168,8 @@
 )
 
 def test_rewrite_getfield_gc_const(self):
+TP = lltype.GcArray(lltype.Signed)
+NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP))
 self.check_rewrite(
 [p1]
 p2 = getfield_gc(ConstPtr(t), descr=tzdescr)
@@ -174,7 +180,7 @@
 cond_call_gc_wb(p3, 0, descr=P2Rdescr)
 p2 = getfield_gc(p3, descr=tzdescr)
 jump(p2)
-)
+, t=NULL)
 # XXX could do better: G2Rdescr
 
 def test_rewrite_getarrayitem_gc(self):
@@ -300,62 +306,62 @@
 def test_getfield_raw(self):
 self.check_rewrite(
 [i1, i2]
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=?)
 keepalive(i3) # random ignored operation
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=?)
 jump(i3, i4)
 , 
 [i1, i2]
 $INEV
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=?)
 keepalive(i3)
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=?)
 jump(i3, i4)
 )
 
 def test_getfield_raw_over_label(self):
 self.check_rewrite(
 [i1, i2]
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=?)
 label(i1, i2, i3)
-

[pypy-commit] pypy stmgc-c4: typo and change to real descrs

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65191:ceb9b8b28bcf
Date: 2013-07-05 11:04 +0200
http://bitbucket.org/pypy/pypy/changeset/ceb9b8b28bcf/

Log:typo and change to real descrs

diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -306,62 +306,62 @@
 def test_getfield_raw(self):
 self.check_rewrite(
 [i1, i2]
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=tydescr)
 keepalive(i3) # random ignored operation
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=tydescr)
 jump(i3, i4)
 , 
 [i1, i2]
 $INEV
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=tydescr)
 keepalive(i3)
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=tydescr)
 jump(i3, i4)
 )
 
 def test_getfield_raw_over_label(self):
 self.check_rewrite(
 [i1, i2]
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=tydescr)
 label(i1, i2, i3)
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=tydescr)
 jump(i3, i4)
 , 
 [i1, i2]
 $INEV
-i3 = getfield_raw(i1, descr=?)
+i3 = getfield_raw(i1, descr=tydescr)
 label(i1, i2, i3)
 $INEV
-i4 = getfield_raw(i2, descr=?)
+i4 = getfield_raw(i2, descr=tydescr)
 jump(i3, i4)
 )
 
 def test_getarrayitem_raw(self):
 self.check_rewrite(
 [i1, i2]
-i3 = getarrayitem_raw(i1, 5, descr=?)
-i4 = getarrayitem_raw(i2, i3, descr=?)
+i3 = getarrayitem_raw(i1, 5, descr=adescr)
+i4 = getarrayitem_raw(i2, i3, descr=adescr)
 jump(i3, i4)
 , 
 [i1, i2]
 $INEV
-i3 = getarrayitem_raw(i1, 5, descr=?)
-i4 = getarrayitem_raw(i2, i3, descr=?)
+i3 = getarrayitem_raw(i1, 5, descr=adescr)
+i4 = getarrayitem_raw(i2, i3, descr=adescr)
 jump(i3, i4)
 )
 
 def test_rewrite_unrelated_setarrayitem_gcs(self):
 self.check_rewrite(
 [p1, i1, p2, p3, i3, p4]
-setarrayitem_gc(p1, i1, p2, descr=?)
-setarrayitem_gc(p3, i3, p4, descr=?)
+setarrayitem_gc(p1, i1, p2, descr=adescr)
+setarrayitem_gc(p3, i3, p4, descr=adescr)
 jump()
 , 
 [p1, i1, p2, p3, i3, p4]
 cond_call_gc_wb(p1, 0, descr=P2Wdescr)
-setarrayitem_gc(p1, i1, p2, descr=?)
+setarrayitem_gc(p1, i1, p2, descr=adescr)
 cond_call_gc_wb(p3, 0, descr=P2Wdescr)
-setarrayitem_gc(p3, i3, p4, descr=?)
+setarrayitem_gc(p3, i3, p4, descr=adescr)
 jump()
 )
 
@@ -417,9 +417,9 @@
 T = rffi.CArrayPtr(rffi.TIME_T)
 calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T)
 oplist = [
-setfield_raw(i1, i2, descr=?),
-setarrayitem_raw(i1, i2, i3, descr=?),
-setinteriorfield_raw(i1, i2, i3, descr=?),
+setfield_raw(i1, i2, descr=tydescr),
+setarrayitem_raw(i1, i2, i3, descr=tydescr),
+setinteriorfield_raw(i1, i2, i3, descr=adescr),
 call_release_gil(123, descr=calldescr2),
 escape(i1),# a generic unknown operation
 ]
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
@@ -163,7 +163,7 @@
 return 'stmgc_minor_collect();'
 
 def stm_major_collect(funcgen, op):
-return 'stmgcpage_possibly_major_collect(1);}' # forced
+return 'stmgcpage_possibly_major_collect(1);' # forced
 
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: rename of transform2.py to transform.py

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65195:88d375dc39b3
Date: 2013-07-05 13:08 +0200
http://bitbucket.org/pypy/pypy/changeset/88d375dc39b3/

Log:rename of transform2.py to transform.py

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
@@ -141,11 +141,11 @@
 translator = self.translator
 
 if self.config.translation.stm:
-from rpython.translator.stm import transform2
+from rpython.translator.stm import transform
 self.getentrypointptr()# build the wrapper first
 # ^^ this is needed to make sure we see the no-GC wrapper function
 # calling the GC entrypoint function.
-stmtransformer = transform2.STMTransformer(self.translator)
+stmtransformer = transform.STMTransformer(self.translator)
 stmtransformer.transform()
 
 gcpolicyclass = self.get_gcpolicyclass()
diff --git a/rpython/translator/stm/test/test_jitdriver.py 
b/rpython/translator/stm/test/test_jitdriver.py
--- a/rpython/translator/stm/test/test_jitdriver.py
+++ b/rpython/translator/stm/test/test_jitdriver.py
@@ -1,5 +1,5 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.translator.stm.test.transform2_support import BaseTestTransform
+from rpython.translator.stm.test.transform_support import BaseTestTransform
 from rpython.rlib.jit import JitDriver
 
 
diff --git a/rpython/translator/stm/test/test_writebarrier.py 
b/rpython/translator/stm/test/test_writebarrier.py
--- a/rpython/translator/stm/test/test_writebarrier.py
+++ b/rpython/translator/stm/test/test_writebarrier.py
@@ -1,5 +1,5 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.translator.stm.test.transform2_support import BaseTestTransform
+from rpython.translator.stm.test.transform_support import BaseTestTransform
 
 
 class TestTransform(BaseTestTransform):
diff --git a/rpython/translator/stm/test/transform2_support.py 
b/rpython/translator/stm/test/transform_support.py
rename from rpython/translator/stm/test/transform2_support.py
rename to rpython/translator/stm/test/transform_support.py
--- a/rpython/translator/stm/test/transform2_support.py
+++ b/rpython/translator/stm/test/transform_support.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import lltype, opimpl
 from rpython.rtyper.llinterp import LLFrame
 from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache
-from rpython.translator.stm.transform2 import STMTransformer
+from rpython.translator.stm.transform import STMTransformer
 from rpython.translator.stm.writebarrier import MORE_PRECISE_CATEGORIES
 from rpython.conftest import option
 
diff --git a/rpython/translator/stm/transform2.py 
b/rpython/translator/stm/transform.py
rename from rpython/translator/stm/transform2.py
rename to rpython/translator/stm/transform.py
--- a/rpython/translator/stm/transform2.py
+++ b/rpython/translator/stm/transform.py
@@ -1,3 +1,10 @@
+from rpython.translator.backendopt.writeanalyze import WriteAnalyzer
+from rpython.translator.stm.writebarrier import insert_stm_barrier
+from rpython.translator.stm.inevitable import insert_turn_inevitable
+from rpython.translator.stm.jitdriver import reorganize_around_jit_driver
+from rpython.translator.stm.threadlocalref import transform_tlref
+from rpython.translator.c.support import log
+
 
 class STMTransformer(object):
 
@@ -18,38 +25,27 @@
 self.print_logs_after_gc()
 
 def transform_write_barrier(self):
-from rpython.translator.backendopt.writeanalyze import WriteAnalyzer
-from rpython.translator.stm.writebarrier import insert_stm_barrier
-#
 self.write_analyzer = WriteAnalyzer(self.translator)
 for graph in self.translator.graphs:
 insert_stm_barrier(self, graph)
 del self.write_analyzer
 
 def transform_turn_inevitable(self):
-from rpython.translator.stm.inevitable import insert_turn_inevitable
-#
 for graph in self.translator.graphs:
 insert_turn_inevitable(graph)
 
 def transform_jit_driver(self):
-from rpython.translator.stm.jitdriver import 
reorganize_around_jit_driver
-#
 for graph in self.translator.graphs:
 reorganize_around_jit_driver(self, graph)
 
 def transform_threadlocalref(self):
-from rpython.translator.stm.threadlocalref import transform_tlref
 transform_tlref(self.translator)
 
 def start_log(self):
-from rpython.translator.c.support import log
 log.info(Software Transactional Memory transformation)
 
 def print_logs(self):
-from rpython.translator.c.support import log
 log.info(Software Transactional Memory transformation applied)
 
 def print_logs_after_gc(self):
-from rpython.translator.c.support import log
 log.info(Software Transactional 

[pypy-commit] pypy stmgc-c4: add new resops COND_CALL_STM_WB and COND_CALL_STM_RB

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65196:675a3d0878f1
Date: 2013-07-05 13:23 +0200
http://bitbucket.org/pypy/pypy/changeset/675a3d0878f1/

Log:add new resops COND_CALL_STM_WB and COND_CALL_STM_RB

diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -121,8 +121,13 @@
 except KeyError:
 return v_base# no barrier needed
 args = [v_base, self.c_zero]
-self.newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
+if target_category == 'W':
+op = rop.COND_CALL_STM_WB
+else:
+op = rop.COND_CALL_STM_RB
+self.newops.append(ResOperation(op, args, None,
 descr=write_barrier_descr))
+
 self.known_category[v_base] = target_category
 return v_base
 
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -44,7 +44,7 @@
 jump()
 , 
 [p1, p2]
-cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, 0, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 jump()
 )
@@ -59,7 +59,7 @@
 , 
 [p1, p2]
 p3 = same_as(ConstPtr(t))
-cond_call_gc_wb(p3, 0, descr=P2Wdescr)
+cond_call_stm_wb(p3, 0, descr=P2Wdescr)
 setfield_gc(p3, p2, descr=tzdescr)
 jump()
 , t=NULL)
@@ -87,9 +87,9 @@
 jump()
 , 
 [p1, p2, p3, p4]
-cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, 0, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
-cond_call_gc_wb(p3, 0, descr=P2Wdescr)
+cond_call_stm_wb(p3, 0, descr=P2Wdescr)
 setfield_gc(p3, p4, descr=tzdescr)
 jump()
 )
@@ -102,7 +102,7 @@
 jump()
 , 
 [p1, p2, i3]
-cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, 0, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 setfield_gc(p1, i3, descr=tydescr)
 jump()
@@ -117,10 +117,10 @@
 jump(p1)
 , 
 [p1, p2, i3]
-cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, 0, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 label(p1, i3)
-cond_call_gc_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, 0, descr=P2Wdescr)
 setfield_gc(p1, i3, descr=tydescr)
 jump(p1)
 )
@@ -162,7 +162,7 @@
 jump(p2)
 , 
 [p1]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 p2 = getfield_gc(p1, descr=tzdescr)
 jump(p2)
 )
@@ -177,7 +177,7 @@
 , 
 [p1]
 p3 = same_as(ConstPtr(t))
-cond_call_gc_wb(p3, 0, descr=P2Rdescr)
+cond_call_stm_rb(p3, 0, descr=P2Rdescr)
 p2 = getfield_gc(p3, descr=tzdescr)
 jump(p2)
 , t=NULL)
@@ -190,7 +190,7 @@
 jump(i3)
 , 
 [p1, i2]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 i3 = getarrayitem_gc(p1, i2, descr=adescr)
 jump(i3)
 )
@@ -202,7 +202,7 @@
 jump(i3)
 , 
 [p1, i2]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 i3 = getinteriorfield_gc(p1, i2, descr=adescr)
 jump(i3)
 )
@@ -215,7 +215,7 @@
 jump(p2, i2)
 , 
 [p1]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 p2 = getfield_gc(p1, descr=tzdescr)
 i2 = getfield_gc(p1, descr=tydescr)
 jump(p2, i2)
@@ -229,9 +229,9 @@
 jump(p2, i2)
 , 
 [p1]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 p2 = getfield_gc(p1, descr=tzdescr)
-cond_call_gc_wb(p2, 0, descr=P2Rdescr)
+cond_call_stm_rb(p2, 0, descr=P2Rdescr)
 i2 = getfield_gc(p2, descr=tydescr)
 jump(p2, i2)
 )
@@ -247,10 +247,10 @@
 jump(p1)
 , 
 [p1]
-cond_call_gc_wb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, 0, descr=P2Rdescr)
 i1 = getfield_gc(p1, descr=tydescr)
  

[pypy-commit] pypy stmgc-c4: I guess those tests need to be rewritten for STM_WB/RB. Still, remove syntax errors.

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65197:dfde347f3c17
Date: 2013-07-05 13:49 +0200
http://bitbucket.org/pypy/pypy/changeset/dfde347f3c17/

Log:I guess those tests need to be rewritten for STM_WB/RB. Still,
remove syntax errors.

diff --git a/rpython/jit/backend/llsupport/test/test_gc.py 
b/rpython/jit/backend/llsupport/test/test_gc.py
--- a/rpython/jit/backend/llsupport/test/test_gc.py
+++ b/rpython/jit/backend/llsupport/test/test_gc.py
@@ -213,7 +213,7 @@
 gc_ll_descr = self.gc_ll_descr
 llop1 = self.llop1
 #
-rewriter = gc.GcRewriterAssembler(gc_ll_descr, None)
+rewriter = GcRewriterAssembler(gc_ll_descr, None)
 newops = rewriter.newops
 v_base = BoxPtr()
 v_value = BoxPtr()
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -4242,3 +4242,14 @@
 assert rffi.cast(lltype.Signed, a[0]) == -7654
 assert rffi.cast(lltype.Signed, a[1]) == 777
 lltype.free(a, flavor='raw')
+
+class WBDescrForTests(AbstractDescr):
+returns_modified_object = False
+wb_slowpath = (0, 0, 0, 0)
+def get_wb_slowpath(self, c1, c2):
+return self.wb_slowpath[c1+2*c2]
+def set_wb_slowpath(self, c1, c2, addr):
+i = c1+2*c2
+self.wb_slowpath = (self.wb_slowpath[:i] + (addr,) +
+self.wb_slowpath[i+1:])
+
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: missing import

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65194:ccb4307abb9c
Date: 2013-07-05 12:15 +0200
http://bitbucket.org/pypy/pypy/changeset/ccb4307abb9c/

Log:missing import

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, rffi
+from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.extregistry import ExtRegistryEntry
 
@@ -31,7 +31,7 @@
 pass #stmgcintf.StmOperations.abort_info_pop(count)
 
 def charp_inspect_abort_info():
-pass # return stmgcintf.StmOperations.inspect_abort_info()
+return rffi.NULL # return stmgcintf.StmOperations.inspect_abort_info()
 
 def abort_and_retry():
 pass # stmgcintf.StmOperations.abort_and_retry()
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: try to satisfy tests..

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65199:fa4f9e6e4a11
Date: 2013-07-05 14:38 +0200
http://bitbucket.org/pypy/pypy/changeset/fa4f9e6e4a11/

Log:try to satisfy tests..

diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -92,7 +92,7 @@
 self._build_wb_slowpath(False, withfloats=True)
 self._build_wb_slowpath(True, withfloats=True)
 self._build_propagate_exception_path()
-if gc_ll_descr.get_malloc_slowpath_addr is not None:
+if gc_ll_descr.get_malloc_slowpath_addr() is not None:
 # generate few slowpaths for various cases
 self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed')
 self.malloc_slowpath_varsize = self._build_malloc_slowpath(
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -241,6 +241,9 @@
 return self.malloc_array(arraydescr.basesize, num_elem,
  arraydescr.itemsize,
  arraydescr.lendescr.offset)
+
+def get_malloc_slowpath_addr(self):
+return None
 
 # 
 # All code below is for the hybrid or minimark GC
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: extract stm barriers from normal write barrier

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65200:f2a6fd3f14de
Date: 2013-07-05 15:10 +0200
http://bitbucket.org/pypy/pypy/changeset/f2a6fd3f14de/

Log:extract stm barriers from normal write barrier

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -270,37 +270,24 @@
 rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address)
 return rffi.cast(lltype.Signed, rst_addr)
 
+
 class WriteBarrierDescr(AbstractDescr):
-def __init__(self, gc_ll_descr, stmcat=None):
+def __init__(self, gc_ll_descr):
 self.llop1 = gc_ll_descr.llop1
-self.stmcat = stmcat
-self.returns_modified_object = (stmcat is not None)
-if not self.returns_modified_object:
-self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
-[llmemory.Address], lltype.Void))
-else:
-self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
-[llmemory.Address], llmemory.Address))
+
+self.returns_modified_object = False
+self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+[llmemory.Address], lltype.Void))
+
 self.fielddescr_tid = gc_ll_descr.fielddescr_tid
 self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
 self.HDRPTR = gc_ll_descr.HDRPTR
 #
-if self.stmcat is not None:
-cfunc_name = self.stmcat[2]
-self.wb_failing_case_ptr = rffi.llexternal(
-cfunc_name,
-self.WB_FUNCPTR_MOD.TO.ARGS,
-self.WB_FUNCPTR_MOD.TO.RESULT,
-sandboxsafe=True,
-_nowrapper=True)
-#
 GCClass = gc_ll_descr.GCClass
 if GCClass is None: # for tests
 return
-if self.stmcat is None:
-self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
-else:
-self.jit_wb_if_flag = self.stmcat[0]
+
+self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
 self.jit_wb_if_flag_byteofs, self.jit_wb_if_flag_singlebyte = (
 self.extract_flag_byte(self.jit_wb_if_flag))
 #
@@ -320,11 +307,7 @@
 self.wb_slowpath = [0, 0, 0, 0]
 
 def repr_of_descr(self):
-if self.stmcat is None:
-return 'wbdescr'
-else:
-cat = self.stmcat[1]
-return cat
+return 'wbdescr'
 
 def __repr__(self):
 return 'WriteBarrierDescr %r' % (self.repr_of_descr(),)
@@ -395,7 +378,41 @@
 if returns_modified_object:
 return gcref_struct
 
+class STMBarrierDescr(WriteBarrierDescr):
+def __init__(self, gc_ll_descr, stmcat, cfunc_name):
+WriteBarrierDescr.__init__(self, gc_ll_descr)
+self.stmcat = stmcat
+self.returns_modified_object = True
+self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
+[llmemory.Address], llmemory.Address))
 
+self.wb_failing_case_ptr = rffi.llexternal(
+cfunc_name,
+self.WB_FUNCPTR_MOD.TO.ARGS,
+self.WB_FUNCPTR_MOD.TO.RESULT,
+sandboxsafe=True,
+_nowrapper=True)
+
+def repr_of_descr(self):
+cat = self.stmcat
+return cat
+
+def _do_barrier(self, gcref_struct, returns_modified_object):
+raise NotImplemented
+
+class STMReadBarrierDescr(STMBarrierDescr):
+def __init__(self, gc_ll_descr, stmcat):
+assert stmcat == 'P2R'
+STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
+ 'stm_DirectReadBarrier')
+
+class STMWriteBarrierDescr(STMBarrierDescr):
+def __init__(self, gc_ll_descr, stmcat):
+assert stmcat in ['P2W', 'R2W']
+STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
+ 'stm_WriteBarrier')
+
+
 class GcLLDescr_framework(GcLLDescription):
 DEBUG = False# forced to True by x86/test/test_zrpy_gc.py
 kind = 'framework'
@@ -494,14 +511,9 @@
 self.do_write_barrier = do_write_barrier
 
 def _setup_barriers_for_stm(self):
-from rpython.memory.gc import stmgc
-WBDescr = WriteBarrierDescr
-self.P2Rdescr = WBDescr(self, (0,  'P2R',
-   'stm_DirectReadBarrier'))
-self.P2Wdescr = WBDescr(self, (0, 'P2W',
-   'stm_WriteBarrier'))
-self.R2Wdescr = WBDescr(self, (0, 'R2W',
-   'stm_WriteBarrierFromReady'))
+self.P2Rdescr = STMReadBarrierDescr(self, 'P2R')
+self.P2Wdescr = STMWriteBarrierDescr(self, 'P2W')
+self.R2Wdescr = STMWriteBarrierDescr(self, 'R2W')
 self.write_barrier_descr = wbdescr: do not use
 #
 @specialize.argtype(0)
___
pypy-commit mailing list
pypy-commit@python.org

[pypy-commit] pypy stmgc-c4: no fastpath for gc write/read barriers

2013-07-05 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65201:43aaaf023f46
Date: 2013-07-05 16:58 +0200
http://bitbucket.org/pypy/pypy/changeset/43aaaf023f46/

Log:no fastpath for gc write/read barriers

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -362,7 +362,7 @@
 self.wb_slowpath[withcards + 2 * withfloats] = addr
 
 @specialize.arg(2)
-def _do_write_barrier(self, gcref_struct, returns_modified_object):
+def _do_barrier(self, gcref_struct, returns_modified_object):
 assert self.returns_modified_object == returns_modified_object
 hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct)
 hdr_addr -= self.gcheaderbuilder.size_gc_header
@@ -397,20 +397,29 @@
 cat = self.stmcat
 return cat
 
+@specialize.arg(2)
 def _do_barrier(self, gcref_struct, returns_modified_object):
-raise NotImplemented
+assert self.returns_modified_object == returns_modified_object
+# XXX: fastpath for Read and Write variants
+funcptr = self.get_barrier_funcptr(returns_modified_object)
+res = funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
+if returns_modified_object:
+return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
+
 
 class STMReadBarrierDescr(STMBarrierDescr):
 def __init__(self, gc_ll_descr, stmcat):
 assert stmcat == 'P2R'
 STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- 'stm_DirectReadBarrier')
+ 'stm_read_barrier')
+
+
 
 class STMWriteBarrierDescr(STMBarrierDescr):
 def __init__(self, gc_ll_descr, stmcat):
 assert stmcat in ['P2W', 'R2W']
 STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- 'stm_WriteBarrier')
+ 'stm_write_barrier')
 
 
 class GcLLDescr_framework(GcLLDescription):
@@ -507,7 +516,7 @@
 else:
 self.write_barrier_descr = WriteBarrierDescr(self)
 def do_write_barrier(gcref_struct, gcref_newptr):
-self.write_barrier_descr._do_write_barrier(gcref_struct, False)
+self.write_barrier_descr._do_barrier(gcref_struct, False)
 self.do_write_barrier = do_write_barrier
 
 def _setup_barriers_for_stm(self):
@@ -524,7 +533,7 @@
 descr = self.P2Wdescr
 else:
 descr = self.P2Rdescr
-return descr._do_write_barrier(gcref, True)
+return descr._do_barrier(gcref, True)
 self.do_stm_barrier = do_stm_barrier
 
 def _make_functions(self, really_not_translated):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: fix

2013-07-08 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r371:1183d4c7518c
Date: 2013-07-08 11:17 +0200
http://bitbucket.org/pypy/stmgc/changeset/1183d4c7518c/

Log:fix

diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -271,7 +271,9 @@
 
 DuObject *du_list(DuObject *cons, DuObject *locals)
 {
+_du_save2(cons, locals);
 DuObject *list = DuList_New();
+_du_restore2(cons, locals);
 while (cons != Du_None) {
 _du_read1(cons);
 DuObject *expr = _DuCons_CAR(cons);
@@ -299,7 +301,11 @@
 else
 _du_getargs1(container, cons, locals, obj);
 
-return DuContainer_New(obj);
+_du_save2(cons, locals);
+DuObject *container = DuContainer_New(obj);
+_du_restore2(cons, locals);
+
+return container;
 }
 
 DuObject *du_get(DuObject *cons, DuObject *locals)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: backout 840ac0a, demo/trees2.duh seems to crash without tracing

2013-07-08 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r372:2b2561c18ea9
Date: 2013-07-08 11:36 +0200
http://bitbucket.org/pypy/stmgc/changeset/2b2561c18ea9/

Log:backout 840ac0a, demo/trees2.duh seems to crash without tracing

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -225,8 +225,8 @@
 id_copy-h_tid |= GCFLAG_VISITED;
 
 /* XXX: may not always need tracing? */
-//if (!(id_copy-h_tid  GCFLAG_STUB))
-//gcptrlist_insert(objects_to_trace, id_copy);
+if (!(id_copy-h_tid  GCFLAG_STUB))
+gcptrlist_insert(objects_to_trace, id_copy);
 } 
 else {
 /* prebuilt originals won't get collected anyway
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: repeat/do write barrier after minor_collection. I think the problem was that minor_collect clears old_objects_to_trace and the object needs to be reregistered there if it

2013-07-08 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r373:470bcb38a12e
Date: 2013-07-08 13:26 +0200
http://bitbucket.org/pypy/stmgc/changeset/470bcb38a12e/

Log:repeat/do write barrier after minor_collection. I think the problem
was that minor_collect clears old_objects_to_trace and the object
needs to be reregistered there if it is modified again.

diff --git a/duhton/listobject.c b/duhton/listobject.c
--- a/duhton/listobject.c
+++ b/duhton/listobject.c
@@ -75,7 +75,7 @@
 
 void _list_append(DuListObject *ob, DuObject *x)
 {
-_du_write1(ob);
+_du_read1(ob);
 DuTupleObject *olditems = ob-ob_tuple;
 
 _du_read1(olditems);
@@ -85,6 +85,8 @@
 DuTupleObject *newitems = DuTuple_New(newcount);
 _du_restore3(ob, x, olditems);
 
+_du_write1(ob);
+
 for (i=0; inewcount-1; i++)
 newitems-ob_items[i] = olditems-ob_items[i];
 newitems-ob_items[newcount-1] = x;
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: A test that fails. Maybe should fail, waiting for arigato's OK

2013-07-08 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r374:ef8442a75174
Date: 2013-07-08 14:37 +0200
http://bitbucket.org/pypy/stmgc/changeset/ef8442a75174/

Log:A test that fails. Maybe should fail, waiting for arigato's OK

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
@@ -204,6 +204,36 @@
 assert p4 == p2
 assert list_of_read_objects() == [p2]
 
+def test_write_barrier_after_minor_collect():
+# maybe should fail. not sure.
+p = oalloc_refs(1)
+pw = lib.stm_write_barrier(p)
+
+lib.stm_push_root(pw)
+minor_collect()
+r = nalloc(HDR)
+pw = lib.stm_pop_root()
+
+assert pw.h_tid  GCFLAG_OLD
+rawsetptr(pw, 0, r)
+
+# pw not in old_objects_to_trace. A
+# repeated write_barrier before
+# rawsetptr() would fix that
+
+lib.stm_push_root(r)
+minor_collect()
+r2 = lib.stm_pop_root()
+check_nursery_free(r)
+
+pr = lib.stm_read_barrier(p)
+assert r != r2
+# these will fail because pw/pr was
+# not traced in the last minor_collect,
+# because they were not registered in
+# old_objects_to_trace.
+assert getptr(pr, 0) != r
+assert getptr(pr, 0) == r2
 
 def test_id_young_to_old():
 # move out of nursery with shadow original
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: we don't need that extra parameter

2013-07-09 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65282:b29a9e46f214
Date: 2013-07-09 10:04 +0200
http://bitbucket.org/pypy/pypy/changeset/b29a9e46f214/

Log:we don't need that extra parameter

diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -958,10 +958,10 @@
 def execute_cond_call_gc_wb_array(self, descr, a, b, c):
 py.test.skip(cond_call_gc_wb_array not supported)
 
-def execute_cond_call_stm_wb(self, descr, a, b):
+def execute_cond_call_stm_wb(self, descr, a):
 py.test.skip(cond_call_stm_wb not supported)
 
-def execute_cond_call_stm_rb(self, descr, a, b):
+def execute_cond_call_stm_rb(self, descr, a):
 py.test.skip(cond_call_stm_rb not supported)
 
 def execute_keepalive(self, descr, x):
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -9,7 +9,7 @@
 #
 # Any SETFIELD_GC, SETARRAYITEM_GC, SETINTERIORFIELD_GC must be done on a
 # W object.  The operation that forces an object p1 to be W is
-# COND_CALL_STM_WB(p1, 0, descr=x2Wdescr), for x in 'PGORL'.  This
+# COND_CALL_STM_WB(p1, descr=x2Wdescr), for x in 'PGORL'.  This
 # COND_CALL_STM_WB is a bit special because if p1 is not W, it *replaces*
 # its value with the W copy (by changing the register's value and
 # patching the stack location if any).  It's still conceptually the same
@@ -120,7 +120,7 @@
 write_barrier_descr = mpcat[target_category]
 except KeyError:
 return v_base# no barrier needed
-args = [v_base, self.c_zero]
+args = [v_base,]
 if target_category == 'W':
 op = rop.COND_CALL_STM_WB
 else:
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -44,7 +44,7 @@
 jump()
 , 
 [p1, p2]
-cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 jump()
 )
@@ -59,7 +59,7 @@
 , 
 [p1, p2]
 p3 = same_as(ConstPtr(t))
-cond_call_stm_wb(p3, 0, descr=P2Wdescr)
+cond_call_stm_wb(p3, descr=P2Wdescr)
 setfield_gc(p3, p2, descr=tzdescr)
 jump()
 , t=NULL)
@@ -87,9 +87,9 @@
 jump()
 , 
 [p1, p2, p3, p4]
-cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
-cond_call_stm_wb(p3, 0, descr=P2Wdescr)
+cond_call_stm_wb(p3, descr=P2Wdescr)
 setfield_gc(p3, p4, descr=tzdescr)
 jump()
 )
@@ -102,7 +102,7 @@
 jump()
 , 
 [p1, p2, i3]
-cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 setfield_gc(p1, i3, descr=tydescr)
 jump()
@@ -117,10 +117,10 @@
 jump(p1)
 , 
 [p1, p2, i3]
-cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, descr=P2Wdescr)
 setfield_gc(p1, p2, descr=tzdescr)
 label(p1, i3)
-cond_call_stm_wb(p1, 0, descr=P2Wdescr)
+cond_call_stm_wb(p1, descr=P2Wdescr)
 setfield_gc(p1, i3, descr=tydescr)
 jump(p1)
 )
@@ -162,7 +162,7 @@
 jump(p2)
 , 
 [p1]
-cond_call_stm_rb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, descr=P2Rdescr)
 p2 = getfield_gc(p1, descr=tzdescr)
 jump(p2)
 )
@@ -177,7 +177,7 @@
 , 
 [p1]
 p3 = same_as(ConstPtr(t))
-cond_call_stm_rb(p3, 0, descr=P2Rdescr)
+cond_call_stm_rb(p3, descr=P2Rdescr)
 p2 = getfield_gc(p3, descr=tzdescr)
 jump(p2)
 , t=NULL)
@@ -190,7 +190,7 @@
 jump(i3)
 , 
 [p1, i2]
-cond_call_stm_rb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, descr=P2Rdescr)
 i3 = getarrayitem_gc(p1, i2, descr=adescr)
 jump(i3)
 )
@@ -202,7 +202,7 @@
 jump(i3)
 , 
 [p1, i2]
-cond_call_stm_rb(p1, 0, descr=P2Rdescr)
+cond_call_stm_rb(p1, descr=P2Rdescr)
 i3 = getinteriorfield_gc(p1, i2, descr=adescr)
 jump(i3)
 )
@@ -215,7 +215,7 @@
 jump(p2, i2)
  

[pypy-commit] pypy stmgc-c4: skip stm_barriers; no implementation in runner.py

2013-07-09 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65281:5d3354d5a836
Date: 2013-07-08 08:26 +0200
http://bitbucket.org/pypy/pypy/changeset/5d3354d5a836/

Log:skip stm_barriers; no implementation in runner.py

diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -958,6 +958,12 @@
 def execute_cond_call_gc_wb_array(self, descr, a, b, c):
 py.test.skip(cond_call_gc_wb_array not supported)
 
+def execute_cond_call_stm_wb(self, descr, a, b):
+py.test.skip(cond_call_stm_wb not supported)
+
+def execute_cond_call_stm_rb(self, descr, a, b):
+py.test.skip(cond_call_stm_rb not supported)
+
 def execute_keepalive(self, descr, x):
 pass
 
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -9,8 +9,8 @@
 #
 # Any SETFIELD_GC, SETARRAYITEM_GC, SETINTERIORFIELD_GC must be done on a
 # W object.  The operation that forces an object p1 to be W is
-# COND_CALL_GC_WB(p1, 0, descr=x2Wdescr), for x in 'PGORL'.  This
-# COND_CALL_GC_WB is a bit special because if p1 is not W, it *replaces*
+# COND_CALL_STM_WB(p1, 0, descr=x2Wdescr), for x in 'PGORL'.  This
+# COND_CALL_STM_WB is a bit special because if p1 is not W, it *replaces*
 # its value with the W copy (by changing the register's value and
 # patching the stack location if any).  It's still conceptually the same
 # object, but the pointer is different.
diff --git a/rpython/jit/metainterp/executor.py 
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -345,9 +345,9 @@
 if value in (rop.FORCE_TOKEN,
  rop.CALL_ASSEMBLER,
  rop.COND_CALL_GC_WB,
+ rop.COND_CALL_GC_WB_ARRAY,
  rop.COND_CALL_STM_WB,
  rop.COND_CALL_STM_RB,
- rop.COND_CALL_GC_WB_ARRAY,
  rop.DEBUG_MERGE_POINT,
  rop.JIT_DEBUG,
  rop.SETARRAYITEM_RAW,
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] extradoc extradoc: minor corrections

2013-07-09 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: extradoc
Changeset: r4980:53412cc62d31
Date: 2013-07-09 14:31 +0200
http://bitbucket.org/pypy/extradoc/changeset/53412cc62d31/

Log:minor corrections

diff --git a/blog/draft/duhton.rst b/blog/draft/duhton.rst
--- a/blog/draft/duhton.rst
+++ b/blog/draft/duhton.rst
@@ -3,24 +3,24 @@
 ==
 
 As covered in `the previous blog post`_, the STM subproject of PyPy has been
-back on the drawing board and the result of this experiment is an STM-aware
-garbage collector written in C. This is finished by now, thanks to Armin
-and Remi_M work, we have a fully functional garbage collector and STM subsystem
+back on the drawing board. The result of this experiment is an STM-aware
+garbage collector written in C. This is finished by now, thanks to Armin's
+and Remi's work, we have a fully functional garbage collector and a STM system
 that can be used from any C program with enough effort. Using it is more than
 a little mundane, since you have to inserts write and read barriers by hand
 everywhere in your code that reads or writes to garbage collector controlled
-memory. Once we finish PyPy integration, those sort of things would be inserted
-automatically by STM transformation in the interpreter.
+memory. Once we finish PyPy integration, this manual work is done automatically
+by the STM transformation in the interpreter.
 
 However, to experiment some more, we created a `lisp interpreter`_
-(called duhton), that follows closely CPython's implementation strategy
-and for anyone familiar with CPython's source code, it should be pretty
+(called Duhton), that follows closely CPython's implementation strategy.
+For anyone familiar with CPython's source code, it should be pretty
 readable. This interpreter works like a normal and very basic lisp variant,
-however it comes with ``(transaction`` builtin, that lets you spawn 
transactions
-using STM system. We implemented a few demos that let you play with the
+however it comes with a ``transaction`` builtin, that lets you spawn 
transactions
+using the STM system. We implemented a few demos that let you play with the
 transaction system. All the demos are running without conflicts, which means
-there is no conflicting writes to global memory and hence are amenable to
-parallelization very well. They exercise:
+there are no conflicting writes to global memory and hence the demos are very
+amenable to parallelization. They exercise:
 
 * arithmetics - ``demo/many_sqare_roots.duh``
 
@@ -29,6 +29,6 @@
 * read-write access to local objects - ``demo/trees2.duh``
 
 With the latter ones being very similar to the classic gcbench. STM-aware
-duhton can be found in `the stmgc repo`_, while the STM-less duhton,
+Duhton can be found in `the stmgc repo`_, while the STM-less Duhton,
 that uses refcounting, can be found in `the duhton repo`_ under the ``base``
 branch.
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original: seems to be working mostly

2013-07-09 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r379:5a4649117329
Date: 2013-07-09 18:22 +0200
http://bitbucket.org/pypy/stmgc/changeset/5a4649117329/

Log:seems to be working mostly

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -945,6 +945,7 @@
   revision_t my_lock = d-my_lock;
   wlog_t *item;
 
+  dprintf((acquire_locks\n));
   assert(!stm_has_got_any_lock(d));
   assert(d-public_descriptor-stolen_objects.size == 0);
 
@@ -957,6 +958,7 @@
   revision_t v;
 retry:
   assert(R-h_tid  GCFLAG_PUBLIC);
+  assert(R-h_tid  GCFLAG_PUBLIC_TO_PRIVATE);
   v = ACCESS_ONCE(R-h_revision);
   if (IS_POINTER(v)) /* has a more recent revision */
 {
@@ -989,7 +991,7 @@
 static void CancelLocks(struct tx_descriptor *d)
 {
   wlog_t *item;
-
+  dprintf((cancel_locks\n));
   if (!g2l_any_entry(d-public_to_private))
 return;
 
@@ -1257,7 +1259,7 @@
   revision_t cur_time;
   struct tx_descriptor *d = thread_descriptor;
   assert(d-active = 1);
-
+  dprintf((CommitTransaction(%p)\n, d));
   spinlock_acquire(d-public_descriptor-collection_lock, 'C');  /*committing*/
   if (d-public_descriptor-stolen_objects.size != 0)
 stm_normalize_stolen_objects(d);
@@ -1341,6 +1343,7 @@
   d-active = 2;
   d-reads_size_limit_nonatomic = 0;
   update_reads_size_limit(d);
+  dprintf((make_inevitable(%p)\n, d));
 }
 
 static revision_t acquire_inev_mutex_and_mark_global_cur_time(
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -370,8 +370,65 @@
 for (; pobj != pend; pobj++) {
 obj = *pobj;
 assert(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL);
-assert(IS_POINTER(obj-h_revision));
-visit((gcptr *)obj-h_revision);
+//assert(IS_POINTER(obj-h_revision));
+
+gcptr next = (gcptr)obj-h_revision;
+/* XXX: do better. visit obj first and then
+   copy over if possible: */
+if (!(obj-h_revision  1)
+ (next-h_revision  1)
+ !(next-h_tid  GCFLAG_VISITED)
+ (next-h_tid  GCFLAG_OLD)
+ !(next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE) /* XXX */
+ !(obj-h_tid  GCFLAG_PUBLIC_TO_PRIVATE)) {
+
+assert(next-h_original == (revision_t)obj);
+assert(next-h_tid  GCFLAG_PUBLIC);
+assert(!(next-h_tid  GCFLAG_STUB));
+assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+assert(!(next-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+assert(!(obj-h_tid  GCFLAG_BACKUP_COPY));
+assert(!(next-h_tid  GCFLAG_BACKUP_COPY));
+
+
+revision_t pre_hash = obj-h_original;
+revision_t old_tid = obj-h_tid;
+memcpy(obj, next, stmgc_size(next));
+assert(!((obj-h_tid ^ old_tid)
+  (GCFLAG_BACKUP_COPY | GCFLAG_STUB
+| GCFLAG_PUBLIC | GCFLAG_HAS_ID
+| GCFLAG_PRIVATE_FROM_PROTECTED)));
+obj-h_original = pre_hash;
+obj-h_tid = old_tid;
+
+fprintf(stdout, copy %p over prebuilt %p\n, next, obj);
+
+/* will not be freed anyway and visit() only traces
+   head revision if not visited already */
+obj-h_tid = ~GCFLAG_VISITED;
+/* For those visiting later:
+   XXX: don't: they will think that they are outdated*/
+next-h_revision = (revision_t)obj;
+//if (next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE) {
+// may have already lost it
+/* mark somehow so that we can update pub_to_priv
+ for inevitable transactions and others ignore
+ it during tracing. Otherwise, inev transactions
+ will think 'next' is outdated. */
+next-h_tid = ~GCFLAG_OLD;
+//}
+}
+else if (IS_POINTER(obj-h_revision)) {
+visit((gcptr *)obj-h_revision);
+}
+
+// prebuilt originals will always be traced
+// in visit_keep. And otherwise, they may
+// not lose their pub_to_priv flag
+// I think because transactions abort
+// without clearing the flags.
+obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
+gcptrlist_insert(objects_to_trace, obj);
 }
 }
 
@@ -410,24 +467,45 @@
 
 /* the current transaction's private copies of public objects */
 wlog_t *item;
+if (1 || d-active == 2) {
+/* inevitable transactions need to have their pub_to_priv
+   fixed. Otherwise, they'll think their objects got outdated */
+/* XXX: others too, but maybe not worth it */
+struct G2L new_public_to_private;
+memset(new_public_to_private, 0, sizeof(struct G2L));
+
+fprintf(stdout, start fixup (%p):\n, d);
+G2L_LOOP_FORWARD(d-public_to_private, item) {
+gcptr R = item-addr;
+ 

[pypy-commit] stmgc copy-over-original: test current approach

2013-07-10 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r380:f6e27ee66d12
Date: 2013-07-10 07:54 +0200
http://bitbucket.org/pypy/stmgc/changeset/f6e27ee66d12/

Log:test current approach

diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -308,6 +308,23 @@
 check_free_old(p2)
 check_not_free(p3) # XXX replace with p1
 
+def test_prebuilt_version_2_copy_over_prebuilt():
+p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
+p2 = oalloc(HDR); make_public(p2)
+p3 = oalloc(HDR); make_public(p3)
+delegate(p1, p2)
+delegate_original(p1, p2)
+delegate(p2, p3)
+delegate_original(p1, p3)
+major_collect()
+# XXX: current approach requires 2 major collections.
+# the first to compress the path
+# the second to do the copy
+major_collect()
+check_prebuilt(p1)
+check_free_old(p2)
+check_free_old(p3)
+
 def test_prebuilt_version_to_protected():
 p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
 p2 = lib.stm_write_barrier(p1)
@@ -321,6 +338,24 @@
 check_prebuilt(p1)
 check_not_free(p2) # XXX replace with p1
 
+def test_prebuilt_version_to_protected_copy_over_prebuilt():
+py.test.skip(current copy-over-prebuilt-original approach
+does not work with public_prebuilt-protected)
+p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
+p2 = lib.stm_write_barrier(p1)
+lib.stm_commit_transaction()
+lib.stm_begin_inevitable_transaction()
+minor_collect()
+p2 = lib.stm_read_barrier(p1)
+assert p2 != p1
+minor_collect()
+major_collect()
+major_collect()
+print classify(p2)
+check_prebuilt(p1)
+check_free_old(p2)
+
+
 def test_private():
 p1 = nalloc(HDR)
 lib.stm_push_root(p1)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original: do a bit more

2013-07-10 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r381:c1d5e6f19828
Date: 2013-07-10 08:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/c1d5e6f19828/

Log:do a bit more

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -367,68 +367,70 @@
 gcptr *pobj = stm_prebuilt_gcroots.items;
 gcptr *pend = stm_prebuilt_gcroots.items + stm_prebuilt_gcroots.size;
 gcptr obj;
+
 for (; pobj != pend; pobj++) {
 obj = *pobj;
 assert(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL);
-//assert(IS_POINTER(obj-h_revision));
+
+if (IS_POINTER(obj-h_revision)) {
+visit((gcptr *)obj-h_revision);
+gcptr next = (gcptr)obj-h_revision;
+
+if (IS_POINTER((revision_t)next) /* needs to be an object */
+ (next-h_revision  1) /* needs to be a head rev */
+ !(obj-h_tid  GCFLAG_PUBLIC_TO_PRIVATE)) {
+
+/* XXX: WHY? */
+assert(!(next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE));
+
+assert(next-h_tid  GCFLAG_OLD); /* not moved already */
+assert(next-h_original == (revision_t)obj);
+assert(next-h_tid  GCFLAG_PUBLIC);
+assert(!(next-h_tid  GCFLAG_STUB));
+assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+assert(!(next-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+assert(!(obj-h_tid  GCFLAG_BACKUP_COPY));
+assert(!(next-h_tid  GCFLAG_BACKUP_COPY));
+
+/* copy next over obj but preserve possibly existing
+   pre-hash value and tid (prebuilt-flag) */
+revision_t pre_hash = obj-h_original;
+revision_t old_tid = obj-h_tid;
+memcpy(obj, next, stmgc_size(next));
+assert(!((obj-h_tid ^ old_tid)
+  (GCFLAG_BACKUP_COPY | GCFLAG_STUB
+| GCFLAG_PUBLIC | GCFLAG_HAS_ID
+| GCFLAG_PRIVATE_FROM_PROTECTED)));
+obj-h_original = pre_hash;
+obj-h_tid = old_tid;
+
+fprintf(stdout, copy %p over prebuilt %p\n, next, obj);
+
+/* Add this copied-over head revision to objects_to_trace
+   because it (next) was added by the preceeding visit() 
+   but not at its new location (obj): */
+gcptrlist_insert(objects_to_trace, obj);
 
-gcptr next = (gcptr)obj-h_revision;
-/* XXX: do better. visit obj first and then
-   copy over if possible: */
-if (!(obj-h_revision  1)
- (next-h_revision  1)
- !(next-h_tid  GCFLAG_VISITED)
- (next-h_tid  GCFLAG_OLD)
- !(next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE) /* XXX */
- !(obj-h_tid  GCFLAG_PUBLIC_TO_PRIVATE)) {
+/* For those visiting later: */
+next-h_revision = (revision_t)obj;
 
-assert(next-h_original == (revision_t)obj);
-assert(next-h_tid  GCFLAG_PUBLIC);
-assert(!(next-h_tid  GCFLAG_STUB));
-assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
-assert(!(next-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
-assert(!(obj-h_tid  GCFLAG_BACKUP_COPY));
-assert(!(next-h_tid  GCFLAG_BACKUP_COPY));
+/* mark somehow so that we can update pub_to_priv
+   for inevitable transactions and others ignore
+   it during tracing. Otherwise, inev transactions
+   will think 'next' is outdated. */
+next-h_tid = ~GCFLAG_OLD;
 
-
-revision_t pre_hash = obj-h_original;
-revision_t old_tid = obj-h_tid;
-memcpy(obj, next, stmgc_size(next));
-assert(!((obj-h_tid ^ old_tid)
-  (GCFLAG_BACKUP_COPY | GCFLAG_STUB
-| GCFLAG_PUBLIC | GCFLAG_HAS_ID
-| GCFLAG_PRIVATE_FROM_PROTECTED)));
-obj-h_original = pre_hash;
-obj-h_tid = old_tid;
+}
+/* obj does not need tracing if it can't
+   be reached from somewhere else*/
+}
+else {
+gcptrlist_insert(objects_to_trace, obj);
+}
 
-fprintf(stdout, copy %p over prebuilt %p\n, next, obj);
-
-/* will not be freed anyway and visit() only traces
-   head revision if not visited already */
-obj-h_tid = ~GCFLAG_VISITED;
-/* For those visiting later:
-   XXX: don't: they will think that they are outdated*/
-next-h_revision = (revision_t)obj;
-//if (next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE) {
-// may have already lost it

[pypy-commit] stmgc default: fix writing to write-ready objects after a minor collection

2013-07-10 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r382:191c168da60e
Date: 2013-07-11 06:40 +0200
http://bitbucket.org/pypy/stmgc/changeset/191c168da60e/

Log:fix writing to write-ready objects after a minor collection

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -125,6 +125,9 @@
 }
 
 //
+/* list for private/protected, old roots that need to be
+   kept in old_objects_to_trace */
+static __thread struct GcPtrList private_or_protected_roots = {0, 0, NULL};
 
 static inline gcptr create_old_object_copy(gcptr obj)
 {
@@ -204,6 +207,22 @@
(revision_t)END_MARKER_ON)) {
 /* 'item' is a regular, non-null pointer */
 visit_if_young(end);
+
+/* if old, private or protected, this object needs to be
+   traced again in the next minor_collect if it is
+   currently in old_objects_to_trace. Because then
+   it may be seen as write-ready in the view of
+   someone:
+   pw = write_barrier(); push_root(pw);
+   minor_collect(); pw = pop_root(); // pw still write-ready
+*/
+if (item  item-h_tid  GCFLAG_OLD
+ !(item-h_tid  GCFLAG_WRITE_BARRIER) /* not set in
+  obj_to_trace*/
+ (item-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
+|| item-h_revision == stm_private_rev_num)) {
+gcptrlist_insert(private_or_protected_roots, item);
+}
 }
 else if (item != NULL) {
 if (item == END_MARKER_OFF)
@@ -358,6 +377,19 @@
 
 stmgc_trace(obj, visit_if_young);
 }
+
+while (gcptrlist_size(private_or_protected_roots)  0) {
+gcptr obj = gcptrlist_pop(private_or_protected_roots);
+/* if it has the write_barrier flag, clear it so that
+   it doesn't get inserted twice by a later write-barrier */
+if (obj-h_tid  GCFLAG_WRITE_BARRIER) {
+/* only insert those that were in old_obj_to_trace
+   and that we didn't insert already */
+obj-h_tid = ~GCFLAG_WRITE_BARRIER;
+gcptrlist_insert(d-old_objects_to_trace, obj);
+dprintf((re-add %p to old_objects_to_trace\n, obj));
+}
+}
 }
 
 static void fix_list_of_read_objects(struct tx_descriptor *d)
@@ -406,7 +438,7 @@
 
 static void teardown_minor_collect(struct tx_descriptor *d)
 {
-assert(gcptrlist_size(d-old_objects_to_trace) == 0);
+//assert(gcptrlist_size(d-old_objects_to_trace) == 0);
 assert(gcptrlist_size(d-public_with_young_copy) == 0);
 assert(gcptrlist_size(d-public_descriptor-stolen_objects) == 0);
 
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
@@ -205,36 +205,52 @@
 assert list_of_read_objects() == [p2]
 
 def test_write_barrier_after_minor_collect():
-# maybe should fail. not sure.
 p = oalloc_refs(1)
 pw = lib.stm_write_barrier(p)
 
 lib.stm_push_root(pw)
 minor_collect()
+lib.stm_push_root(ffi.NULL)
+minor_collect()
+lib.stm_pop_root()
+minor_collect()
 r = nalloc(HDR)
 pw = lib.stm_pop_root()
 
 assert pw.h_tid  GCFLAG_OLD
 rawsetptr(pw, 0, r)
 
-# pw not in old_objects_to_trace. A
-# repeated write_barrier before
-# rawsetptr() would fix that
-
+# pw needs to be readded to old_objects_to_trace
+# before the next minor gc in order for this test to pass
 lib.stm_push_root(r)
 minor_collect()
+minor_collect()
+minor_collect()
+q = nalloc(HDR)
 r2 = lib.stm_pop_root()
 check_nursery_free(r)
 
 pr = lib.stm_read_barrier(p)
 assert r != r2
-# these will fail because pw/pr was
-# not traced in the last minor_collect,
-# because they were not registered in
-# old_objects_to_trace.
 assert getptr(pr, 0) != r
 assert getptr(pr, 0) == r2
 
+# the following shouldn't be done
+# because pw was not saved. Just
+# here to check that pw gets removed
+# from old_objects_to_trace when not found
+# on the root stack anymore
+rawsetptr(pw, 0, q)
+lib.stm_push_root(q)
+minor_collect()
+q2 = lib.stm_pop_root()
+check_nursery_free(q)
+pr = lib.stm_read_barrier(p)
+assert q != q2
+assert getptr(pr, 0) == q
+assert getptr(pr, 0) != q2
+
+
 def test_id_young_to_old():
 # move out of nursery with shadow original
 p = nalloc(HDR)
diff --git a/duhton/listobject.c b/duhton/listobject.c
--- a/duhton/listobject.c
+++ b/duhton/listobject.c
@@ -75,7 +75,7 @@
 
 void _list_append(DuListObject *ob, DuObject *x)
 {
-_du_read1(ob);
+_du_write1(ob);
 DuTupleObject *olditems = ob-ob_tuple;
 
 _du_read1(olditems);
@@ -85,8 +85,6 @@
 DuTupleObject *newitems = 

[pypy-commit] stmgc copy-over-original: fix bad cleanup :(

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r386:b2090bd31f4d
Date: 2013-07-11 08:00 +0200
http://bitbucket.org/pypy/stmgc/changeset/b2090bd31f4d/

Log:fix bad cleanup :(

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -589,7 +589,8 @@
 assert(!(obj-h_tid  GCFLAG_STUB));
 
 if (!(obj-h_tid  GCFLAG_OLD)) {
-items[i] = (gcptr)obj-h_revision;
+obj = (gcptr)obj-h_revision;
+items[i] = obj;
 }
 else if (obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
 /* Warning: in case the object listed is outdated and has been
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original: merge default

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r383:ee69aa1b8ef3
Date: 2013-07-11 07:13 +0200
http://bitbucket.org/pypy/stmgc/changeset/ee69aa1b8ef3/

Log:merge default

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -125,6 +125,9 @@
 }
 
 //
+/* list for private/protected, old roots that need to be
+   kept in old_objects_to_trace */
+static __thread struct GcPtrList private_or_protected_roots = {0, 0, NULL};
 
 static inline gcptr create_old_object_copy(gcptr obj)
 {
@@ -204,6 +207,22 @@
(revision_t)END_MARKER_ON)) {
 /* 'item' is a regular, non-null pointer */
 visit_if_young(end);
+
+/* if old, private or protected, this object needs to be
+   traced again in the next minor_collect if it is
+   currently in old_objects_to_trace. Because then
+   it may be seen as write-ready in the view of
+   someone:
+   pw = write_barrier(); push_root(pw);
+   minor_collect(); pw = pop_root(); // pw still write-ready
+*/
+if (item  item-h_tid  GCFLAG_OLD
+ !(item-h_tid  GCFLAG_WRITE_BARRIER) /* not set in
+  obj_to_trace*/
+ (item-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
+|| item-h_revision == stm_private_rev_num)) {
+gcptrlist_insert(private_or_protected_roots, item);
+}
 }
 else if (item != NULL) {
 if (item == END_MARKER_OFF)
@@ -358,6 +377,19 @@
 
 stmgc_trace(obj, visit_if_young);
 }
+
+while (gcptrlist_size(private_or_protected_roots)  0) {
+gcptr obj = gcptrlist_pop(private_or_protected_roots);
+/* if it has the write_barrier flag, clear it so that
+   it doesn't get inserted twice by a later write-barrier */
+if (obj-h_tid  GCFLAG_WRITE_BARRIER) {
+/* only insert those that were in old_obj_to_trace
+   and that we didn't insert already */
+obj-h_tid = ~GCFLAG_WRITE_BARRIER;
+gcptrlist_insert(d-old_objects_to_trace, obj);
+dprintf((re-add %p to old_objects_to_trace\n, obj));
+}
+}
 }
 
 static void fix_list_of_read_objects(struct tx_descriptor *d)
@@ -410,7 +442,7 @@
 
 static void teardown_minor_collect(struct tx_descriptor *d)
 {
-assert(gcptrlist_size(d-old_objects_to_trace) == 0);
+//assert(gcptrlist_size(d-old_objects_to_trace) == 0);
 assert(gcptrlist_size(d-public_with_young_copy) == 0);
 assert(gcptrlist_size(d-public_descriptor-stolen_objects) == 0);
 
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
@@ -205,36 +205,52 @@
 assert list_of_read_objects() == [p2]
 
 def test_write_barrier_after_minor_collect():
-# maybe should fail. not sure.
 p = oalloc_refs(1)
 pw = lib.stm_write_barrier(p)
 
 lib.stm_push_root(pw)
 minor_collect()
+lib.stm_push_root(ffi.NULL)
+minor_collect()
+lib.stm_pop_root()
+minor_collect()
 r = nalloc(HDR)
 pw = lib.stm_pop_root()
 
 assert pw.h_tid  GCFLAG_OLD
 rawsetptr(pw, 0, r)
 
-# pw not in old_objects_to_trace. A
-# repeated write_barrier before
-# rawsetptr() would fix that
-
+# pw needs to be readded to old_objects_to_trace
+# before the next minor gc in order for this test to pass
 lib.stm_push_root(r)
 minor_collect()
+minor_collect()
+minor_collect()
+q = nalloc(HDR)
 r2 = lib.stm_pop_root()
 check_nursery_free(r)
 
 pr = lib.stm_read_barrier(p)
 assert r != r2
-# these will fail because pw/pr was
-# not traced in the last minor_collect,
-# because they were not registered in
-# old_objects_to_trace.
 assert getptr(pr, 0) != r
 assert getptr(pr, 0) == r2
 
+# the following shouldn't be done
+# because pw was not saved. Just
+# here to check that pw gets removed
+# from old_objects_to_trace when not found
+# on the root stack anymore
+rawsetptr(pw, 0, q)
+lib.stm_push_root(q)
+minor_collect()
+q2 = lib.stm_pop_root()
+check_nursery_free(q)
+pr = lib.stm_read_barrier(p)
+assert q != q2
+assert getptr(pr, 0) == q
+assert getptr(pr, 0) != q2
+
+
 def test_id_young_to_old():
 # move out of nursery with shadow original
 p = nalloc(HDR)
diff --git a/duhton/demo/trees.duh b/duhton/demo/trees.duh
--- a/duhton/demo/trees.duh
+++ b/duhton/demo/trees.duh
@@ -1,15 +1,16 @@
 
 (defun create-tree (n)
-   (if ( n 1) (list 1) (list (create-tree (/ n 2)) (create-tree (/ n 2
+   (if (== n 0) 1 (cons (create-tree (- n 1)) (create-tree (- n 1
 )
 
 (defun walk-tree (tree)
-   (if (== (len tree) 1) (get tree 0)
-  (+ 

[pypy-commit] stmgc copy-over-original: typo

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r385:844c3aeccf50
Date: 2013-07-11 07:52 +0200
http://bitbucket.org/pypy/stmgc/changeset/844c3aeccf50/

Log:typo

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -406,7 +406,7 @@
 obj-h_original = pre_hash;
 obj-h_tid = old_tid;
 
-dprintf(stdout, copy %p over prebuilt %p\n, next, obj);
+dprintf((copy %p over prebuilt %p\n, next, obj));
 
 /* Add this copied-over head revision to objects_to_trace
because it (next) was added by the preceeding visit() 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original: cleanups

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r384:2e860d218333
Date: 2013-07-11 07:48 +0200
http://bitbucket.org/pypy/stmgc/changeset/2e860d218333/

Log:cleanups

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -380,12 +380,14 @@
  (next-h_revision  1) /* needs to be a head rev */
  !(obj-h_tid  GCFLAG_PUBLIC_TO_PRIVATE)) {
 
-/* XXX: WHY? */
+/* XXX: WHY never hit? */
 assert(!(next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE));
 
 assert(next-h_tid  GCFLAG_OLD); /* not moved already */
 assert(next-h_original == (revision_t)obj);
-assert(next-h_tid  GCFLAG_PUBLIC);
+assert(next-h_tid  GCFLAG_PUBLIC); /* no priv/prot!
+otherwise we'd need to fix more lists
+like old_objects_to_trace */
 assert(!(next-h_tid  GCFLAG_STUB));
 assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
 assert(!(next-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
@@ -404,7 +406,7 @@
 obj-h_original = pre_hash;
 obj-h_tid = old_tid;
 
-fprintf(stdout, copy %p over prebuilt %p\n, next, obj);
+dprintf(stdout, copy %p over prebuilt %p\n, next, obj);
 
 /* Add this copied-over head revision to objects_to_trace
because it (next) was added by the preceeding visit() 
@@ -422,7 +424,7 @@
 
 }
 /* obj does not need tracing if it can't
-   be reached from somewhere else*/
+   be reached from somewhere else */
 }
 else {
 gcptrlist_insert(objects_to_trace, obj);
@@ -457,6 +459,9 @@
 static void mark_all_stack_roots(void)
 {
 struct tx_descriptor *d;
+struct G2L new_public_to_private;
+memset(new_public_to_private, 0, sizeof(struct G2L));
+
 for (d = stm_tx_head; d; d = d-tx_next) {
 assert(!stm_has_got_any_lock(d));
 
@@ -469,39 +474,36 @@
 
 /* the current transaction's private copies of public objects */
 wlog_t *item;
-if (1 || d-active == 2) {
-/* inevitable transactions need to have their pub_to_priv
-   fixed. Otherwise, they'll think their objects got outdated */
-/* XXX: others too, but maybe not worth it */
-struct G2L new_public_to_private;
-memset(new_public_to_private, 0, sizeof(struct G2L));
 
-fprintf(stdout, start fixup (%p):\n, d);
-G2L_LOOP_FORWARD(d-public_to_private, item) {
-gcptr R = item-addr;
-gcptr L = item-val;
-if (!(R-h_tid  GCFLAG_OLD)) {
-/* R was copied over its original */
-gcptr new_R = (gcptr)R-h_original;
-g2l_insert(new_public_to_private, new_R, L);
-G2L_LOOP_DELETE(item);
-
-if (L-h_revision == (revision_t)R) {
-L-h_revision = (revision_t)new_R;
-fprintf(stdout,  fixup %p to %p - %p\n, R, new_R, 
L);
-}
-else
-fprintf(stdout,  fixup %p to %p - %p\n, R, new_R, 
L);
+/* transactions need to have their pub_to_priv fixed. Otherwise, 
+   they'll think their objects got outdated. Only absolutely
+   necessary for inevitable transactions (XXX check performance?). */
+dprintf((start fixup (%p):\n, d));
+G2L_LOOP_FORWARD(d-public_to_private, item) {
+gcptr R = item-addr;
+gcptr L = item-val;
+if (!(R-h_tid  GCFLAG_OLD)) {
+/* R was copied over its original */
+gcptr new_R = (gcptr)R-h_original;
+g2l_insert(new_public_to_private, new_R, L);
+G2L_LOOP_DELETE(item);
+
+if (L-h_revision == (revision_t)R) {
+L-h_revision = (revision_t)new_R;
+dprintf((  fixup %p to %p - %p\n, R, new_R, L));
 }
-} G2L_LOOP_END;
-
-/* copy to real pub_to_priv */
-G2L_LOOP_FORWARD(new_public_to_private, item) {
-g2l_insert(d-public_to_private, item-addr, item-val);
-} G2L_LOOP_END;
-g2l_delete_not_used_any_more(new_public_to_private);
-}
+else
+dprintf((  fixup %p to %p - %p\n, R, new_R, L));
+}
+} G2L_LOOP_END;
 
+/* copy to real pub_to_priv */
+G2L_LOOP_FORWARD(new_public_to_private, item) {
+g2l_insert(d-public_to_private, item-addr, item-val);
+} G2L_LOOP_END;
+

[pypy-commit] stmgc default: add cache of writeables to demo_random.c and fix a bug

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r387:9c2b50efb633
Date: 2013-07-11 10:13 +0200
http://bitbucket.org/pypy/stmgc/changeset/9c2b50efb633/

Log:add cache of writeables to demo_random.c and fix a bug

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -52,6 +52,12 @@
 // global and per-thread-data
 time_t default_seed;
 gcptr shared_roots[SHARED_ROOTS];
+
+#define CACHE_MASK 65535
+#define CACHE_ENTRIES ((CACHE_MASK + 1) / sizeof(char *))
+#define CACHE_AT(cache, obj) (*(gcptr *)((char *)(cache)   \
+ + ((revision_t)(obj)  CACHE_MASK)))
+
 struct thread_data {
 unsigned int thread_seed;
 gcptr roots[MAXROOTS];
@@ -61,6 +67,7 @@
 int steps_left;
 int interruptible;
 int atomic;
+revision_t writeable[CACHE_ENTRIES];
 };
 __thread struct thread_data td;
 
@@ -140,6 +147,7 @@
 }
 }
 
+__thread revision_t temp_cache[CACHE_ENTRIES];
 void pop_roots()
 {
 int i;
@@ -148,6 +156,8 @@
 td.roots[i] = stm_pop_root();
 check(td.roots[i]);
 }
+/* some objects may have changed positions */
+memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 void del_root(int idx)
@@ -227,6 +237,7 @@
 if (p != NULL) {
 check(p);
 w = stm_write_barrier(p);
+CACHE_AT(td.writeable, w) = w;
 check(w);
 assert(is_private(w));
 }
@@ -298,6 +309,8 @@
 void setup_thread()
 {
 int i;
+memset(td, 0, sizeof(struct thread_data));
+
 td.thread_seed = default_seed++;
 td.steps_left = STEPS_PER_THREAD;
 td.interruptible = 0;
@@ -395,7 +408,10 @@
 break;
 case 7: // set 'p' as *next in one of the roots
 check(_r);
-w_r = (nodeptr)write_barrier(_r);
+if (CACHE_AT(td.writeable, _r) == _r)
+w_r = (nodeptr)_r;
+else
+w_r = (nodeptr)write_barrier(_r);
 check((gcptr)w_r);
 check(p);
 w_r-next = (struct node*)p;
@@ -454,7 +470,10 @@
 assert(w_t-id == stm_id((gcptr)_t));
 }
 else {
-w_t = (nodeptr)write_barrier(_t);
+if (CACHE_AT(td.writeable, _t) == _t)
+w_t = (nodeptr)_t;
+else
+w_t = (nodeptr)write_barrier(_t);
 w_t-id = stm_id((gcptr)w_t);
 assert(w_t-id == stm_id((gcptr)_t));
 }
@@ -470,7 +489,10 @@
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
 else {
-w_t = (nodeptr)write_barrier(_t);
+if (CACHE_AT(td.writeable, _t) == _t)
+w_t = (nodeptr)_t;
+else
+w_t = (nodeptr)write_barrier(_t);
 w_t-hash = stm_hash((gcptr)w_t);
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
@@ -538,6 +560,8 @@
 
 td.interruptible = 0;
 pop_roots();
+
+memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 
@@ -558,6 +582,7 @@
 stm_push_root(end_marker);
 
 int p = run_me();
+
 if (p == -1) // maybe restart transaction
 return get_rand(3) != 1;
 
@@ -567,6 +592,10 @@
 int run_me()
 {
 gcptr p = NULL;
+
+// clear cache of writeables:
+memset(td.writeable, 0, sizeof(td.writeable));
+
 while (td.steps_left--0 || td.atomic) {
 if (td.steps_left % 8 == 0)
 fprintf(stdout, #);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -207,8 +207,8 @@
(revision_t)END_MARKER_ON)) {
 /* 'item' is a regular, non-null pointer */
 visit_if_young(end);
-
-/* if old, private or protected, this object needs to be
+item = *end;
+/* if private or protected, this object needs to be
traced again in the next minor_collect if it is
currently in old_objects_to_trace. Because then
it may be seen as write-ready in the view of
@@ -216,7 +216,7 @@
pw = write_barrier(); push_root(pw);
minor_collect(); pw = pop_root(); // pw still write-ready
 */
-if (item  item-h_tid  GCFLAG_OLD
+if (item
  !(item-h_tid  GCFLAG_WRITE_BARRIER) /* not set in
   obj_to_trace*/
  (item-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
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
@@ -250,6 +250,25 @@
 assert getptr(pr, 0) == q
 assert getptr(pr, 0) != q2
 
+def test_write_barrier_after_minor_collect_young_to_old():
+p = nalloc_refs(1)
+pw = lib.stm_write_barrier(p)
+
+lib.stm_push_root(pw)
+minor_collect()
+r = nalloc(HDR)
+pw = lib.stm_pop_root()
+
+check_nursery_free(p)
+assert pw.h_tid  GCFLAG_OLD
+rawsetptr(pw, 0, r)
+
+

[pypy-commit] stmgc copy-over-original: merge default

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r388:dba9439565bd
Date: 2013-07-11 10:14 +0200
http://bitbucket.org/pypy/stmgc/changeset/dba9439565bd/

Log:merge default

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -52,6 +52,12 @@
 // global and per-thread-data
 time_t default_seed;
 gcptr shared_roots[SHARED_ROOTS];
+
+#define CACHE_MASK 65535
+#define CACHE_ENTRIES ((CACHE_MASK + 1) / sizeof(char *))
+#define CACHE_AT(cache, obj) (*(gcptr *)((char *)(cache)   \
+ + ((revision_t)(obj)  CACHE_MASK)))
+
 struct thread_data {
 unsigned int thread_seed;
 gcptr roots[MAXROOTS];
@@ -61,6 +67,7 @@
 int steps_left;
 int interruptible;
 int atomic;
+revision_t writeable[CACHE_ENTRIES];
 };
 __thread struct thread_data td;
 
@@ -140,6 +147,7 @@
 }
 }
 
+__thread revision_t temp_cache[CACHE_ENTRIES];
 void pop_roots()
 {
 int i;
@@ -148,6 +156,8 @@
 td.roots[i] = stm_pop_root();
 check(td.roots[i]);
 }
+/* some objects may have changed positions */
+memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 void del_root(int idx)
@@ -227,6 +237,7 @@
 if (p != NULL) {
 check(p);
 w = stm_write_barrier(p);
+CACHE_AT(td.writeable, w) = w;
 check(w);
 assert(is_private(w));
 }
@@ -298,6 +309,8 @@
 void setup_thread()
 {
 int i;
+memset(td, 0, sizeof(struct thread_data));
+
 td.thread_seed = default_seed++;
 td.steps_left = STEPS_PER_THREAD;
 td.interruptible = 0;
@@ -395,7 +408,10 @@
 break;
 case 7: // set 'p' as *next in one of the roots
 check(_r);
-w_r = (nodeptr)write_barrier(_r);
+if (CACHE_AT(td.writeable, _r) == _r)
+w_r = (nodeptr)_r;
+else
+w_r = (nodeptr)write_barrier(_r);
 check((gcptr)w_r);
 check(p);
 w_r-next = (struct node*)p;
@@ -454,7 +470,10 @@
 assert(w_t-id == stm_id((gcptr)_t));
 }
 else {
-w_t = (nodeptr)write_barrier(_t);
+if (CACHE_AT(td.writeable, _t) == _t)
+w_t = (nodeptr)_t;
+else
+w_t = (nodeptr)write_barrier(_t);
 w_t-id = stm_id((gcptr)w_t);
 assert(w_t-id == stm_id((gcptr)_t));
 }
@@ -470,7 +489,10 @@
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
 else {
-w_t = (nodeptr)write_barrier(_t);
+if (CACHE_AT(td.writeable, _t) == _t)
+w_t = (nodeptr)_t;
+else
+w_t = (nodeptr)write_barrier(_t);
 w_t-hash = stm_hash((gcptr)w_t);
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
@@ -538,6 +560,8 @@
 
 td.interruptible = 0;
 pop_roots();
+
+memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 
@@ -558,6 +582,7 @@
 stm_push_root(end_marker);
 
 int p = run_me();
+
 if (p == -1) // maybe restart transaction
 return get_rand(3) != 1;
 
@@ -567,6 +592,10 @@
 int run_me()
 {
 gcptr p = NULL;
+
+// clear cache of writeables:
+memset(td.writeable, 0, sizeof(td.writeable));
+
 while (td.steps_left--0 || td.atomic) {
 if (td.steps_left % 8 == 0)
 fprintf(stdout, #);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -207,8 +207,8 @@
(revision_t)END_MARKER_ON)) {
 /* 'item' is a regular, non-null pointer */
 visit_if_young(end);
-
-/* if old, private or protected, this object needs to be
+item = *end;
+/* if private or protected, this object needs to be
traced again in the next minor_collect if it is
currently in old_objects_to_trace. Because then
it may be seen as write-ready in the view of
@@ -216,7 +216,7 @@
pw = write_barrier(); push_root(pw);
minor_collect(); pw = pop_root(); // pw still write-ready
 */
-if (item  item-h_tid  GCFLAG_OLD
+if (item
  !(item-h_tid  GCFLAG_WRITE_BARRIER) /* not set in
   obj_to_trace*/
  (item-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
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
@@ -250,6 +250,25 @@
 assert getptr(pr, 0) == q
 assert getptr(pr, 0) != q2
 
+def test_write_barrier_after_minor_collect_young_to_old():
+p = nalloc_refs(1)
+pw = lib.stm_write_barrier(p)
+
+lib.stm_push_root(pw)
+minor_collect()
+r = nalloc(HDR)
+pw = lib.stm_pop_root()
+
+check_nursery_free(p)
+assert pw.h_tid  GCFLAG_OLD
+rawsetptr(pw, 0, r)
+
+lib.stm_push_root(pw)
+

[pypy-commit] stmgc copy-over-original: free objects that are copied over prebuilts in the same major collection

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: copy-over-original
Changeset: r392:ea61566d33cd
Date: 2013-07-11 12:12 +0200
http://bitbucket.org/pypy/stmgc/changeset/ea61566d33cd/

Log:free objects that are copied over prebuilts in the same major
collection

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -223,6 +223,7 @@
 id_copy-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
 /* see fix_outdated() */
 id_copy-h_tid |= GCFLAG_VISITED;
+assert(id_copy-h_tid  GCFLAG_OLD);
 
 /* XXX: may not always need tracing? */
 if (!(id_copy-h_tid  GCFLAG_STUB))
@@ -249,6 +250,7 @@
 if (!(obj-h_tid  GCFLAG_VISITED)) {
 obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;  /* see fix_outdated() */
 obj-h_tid |= GCFLAG_VISITED;
+assert(obj-h_tid  GCFLAG_OLD);
 gcptrlist_insert(objects_to_trace, obj);
 
 keep_original_alive(obj);
@@ -272,6 +274,7 @@
 obj = (gcptr)(obj-h_revision - 2);
 if (!(obj-h_tid  GCFLAG_PUBLIC)) {
 prev_obj-h_tid |= GCFLAG_VISITED;
+assert(prev_obj-h_tid  GCFLAG_OLD);
 keep_original_alive(prev_obj);
 
 assert(*pobj == prev_obj);
@@ -315,6 +318,9 @@
 
 obj-h_tid |= GCFLAG_VISITED;
 B-h_tid |= GCFLAG_VISITED;
+assert(obj-h_tid  GCFLAG_OLD);
+assert(B-h_tid  GCFLAG_OLD);
+
 assert(!(obj-h_tid  GCFLAG_STUB));
 assert(!(B-h_tid  GCFLAG_STUB));
 gcptrlist_insert2(objects_to_trace, obj, B);
@@ -337,6 +343,7 @@
 if (!(obj-h_tid  GCFLAG_VISITED)) {
 obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;  /* see fix_outdated() */
 obj-h_tid |= GCFLAG_VISITED;
+assert(obj-h_tid  GCFLAG_OLD);
 gcptrlist_insert(objects_to_trace, obj);
 
 if (IS_POINTER(obj-h_revision)) {
@@ -379,20 +386,14 @@
 if (IS_POINTER((revision_t)next) /* needs to be an object */
  (next-h_revision  1) /* needs to be a head rev */
  !(obj-h_tid  GCFLAG_PUBLIC_TO_PRIVATE)) {
-
-/* XXX: WHY never hit? */
-assert(!(next-h_tid  GCFLAG_PUBLIC_TO_PRIVATE));
-
+
+/* next may have had PUBLIC_TO_PRIVATE, but that was
+   cleared in the preceeding visit() */
 assert(next-h_tid  GCFLAG_OLD); /* not moved already */
 assert(next-h_original == (revision_t)obj);
 assert(next-h_tid  GCFLAG_PUBLIC); /* no priv/prot!
 otherwise we'd need to fix more lists
 like old_objects_to_trace */
-assert(!(next-h_tid  GCFLAG_STUB));
-assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
-assert(!(next-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
-assert(!(obj-h_tid  GCFLAG_BACKUP_COPY));
-assert(!(next-h_tid  GCFLAG_BACKUP_COPY));
 
 /* copy next over obj but preserve possibly existing
pre-hash value and tid (prebuilt-flag) */
@@ -420,8 +421,7 @@
for inevitable transactions and others ignore
it during tracing. Otherwise, inev transactions
will think 'next' is outdated. */
-next-h_tid = ~GCFLAG_OLD;
-
+next-h_tid = ~(GCFLAG_OLD | GCFLAG_VISITED);
 }
 /* obj does not need tracing if it can't
be reached from somewhere else */
@@ -571,6 +571,11 @@
 items[i] = items[--d-private_from_protected.size];
 }
 }
+
+/* In old_objects_to_trace there can be a now invalid object 
+   NO: never happens because only priv/prot objects can still
+   be in old_objects_to_trace after the forced minor_collection.
+   And we do not copy such objects over prebuilts. */
 
 /* If we're aborting this transaction anyway, we don't need to do
  * more here.
@@ -756,6 +761,7 @@
 gcptr p = item-addr;
 if (p-h_tid  GCFLAG_VISITED) {
 p-h_tid = ~GCFLAG_VISITED;
+assert(p-h_tid  GCFLAG_OLD);
 }
 else {
 G2L_LOOP_DELETE(item);
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -323,9 +323,6 @@
 check_prebuilt(p1)
 assert lib.stm_hash(p1) == 99
 check_free_old(p2)
-check_not_free(p3)
-# XXX: takes another major collection to free p3
-major_collect()
 check_free_old(p3)
 
 def test_prebuilt_version_to_protected():
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: merge

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r394:19e89845f0a0
Date: 2013-07-11 17:36 +0200
http://bitbucket.org/pypy/stmgc/changeset/19e89845f0a0/

Log:merge

diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -199,7 +199,7 @@
 DuObject *du_div(DuObject *cons, DuObject *locals)
 {
 int result = 0;
-   int first = 1;
+int first = 1;
 
 while (cons != Du_None) {
 _du_read1(cons);
@@ -208,12 +208,12 @@
 
 _du_save2(next, locals);
 DuObject *obj = Du_Eval(expr, locals);
-   if (first) {
-   result = DuInt_AsInt(obj);
-   first = 0;
-   } else {
-   result /= DuInt_AsInt(obj);
-   }
+if (first) {
+result = DuInt_AsInt(obj);
+first = 0;
+} else {
+result /= DuInt_AsInt(obj);
+}
 _du_restore2(next, locals);
 
 cons = next;
@@ -612,8 +612,8 @@
 void Du_Initialize(int num_threads)
 {
 stm_initialize();
-   all_threads_count = num_threads;
-   all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads);
+all_threads_count = num_threads;
+all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads);
 
 DuFrame_SetBuiltinMacro(Du_Globals, progn, Du_Progn);
 DuFrame_SetBuiltinMacro(Du_Globals, setq, du_setq);
@@ -621,7 +621,7 @@
 DuFrame_SetBuiltinMacro(Du_Globals, +, du_add);
 DuFrame_SetBuiltinMacro(Du_Globals, -, du_sub);
 DuFrame_SetBuiltinMacro(Du_Globals, *, du_mul);
-   DuFrame_SetBuiltinMacro(Du_Globals, /, du_div);
+DuFrame_SetBuiltinMacro(Du_Globals, /, du_div);
 DuFrame_SetBuiltinMacro(Du_Globals, , du_lt);
 DuFrame_SetBuiltinMacro(Du_Globals, =, du_le);
 DuFrame_SetBuiltinMacro(Du_Globals, ==, du_eq);
@@ -642,12 +642,12 @@
 DuFrame_SetBuiltinMacro(Du_Globals, defun, du_defun);
 DuFrame_SetBuiltinMacro(Du_Globals, car, du_car);
 DuFrame_SetBuiltinMacro(Du_Globals, cdr, du_cdr);
-   DuFrame_SetBuiltinMacro(Du_Globals, cons, du_cons);
+DuFrame_SetBuiltinMacro(Du_Globals, cons, du_cons);
 DuFrame_SetBuiltinMacro(Du_Globals, not, du_not);
 DuFrame_SetBuiltinMacro(Du_Globals, transaction, du_transaction);
 DuFrame_SetBuiltinMacro(Du_Globals, sleepms, du_sleepms);
 DuFrame_SetBuiltinMacro(Du_Globals, defined?, du_defined);
-   DuFrame_SetBuiltinMacro(Du_Globals, pair?, du_pair);
+DuFrame_SetBuiltinMacro(Du_Globals, pair?, du_pair);
 DuFrame_SetBuiltinMacro(Du_Globals, assert, du_assert);
 DuFrame_SetSymbolStr(Du_Globals, None, Du_None);
 }
diff --git a/duhton/test/test_cons.py b/duhton/test/test_cons.py
--- a/duhton/test/test_cons.py
+++ b/duhton/test/test_cons.py
@@ -10,6 +10,8 @@
 def test_pair():
 assert run((print (pair? 1))) == 0\n
 assert run((print (pair? (cons 1 2 == 1\n
+assert run((setq x (cons 1 2)) (print (pair? x))) == 1\n
+assert run((setq x 42) (print (pair? x))) == 0\n
 
 def test_car_cdr():
 assert run((print (car (quote (2 3) == 2\n
diff --git a/duhton/test/test_int.py b/duhton/test/test_int.py
--- a/duhton/test/test_int.py
+++ b/duhton/test/test_int.py
@@ -20,6 +20,10 @@
 assert evaluate((* 2 3 7)) == 42
 assert evaluate((* (+ 5 1) (+ 6 1))) == 42
 
+def test_div():
+assert evaluate((/ 11 2)) == 5
+assert evaluate((/ 29 2 3)) == 4
+
 def test_cmp():
 assert evaluate((  6 6)) == 0
 assert evaluate((= 6 6)) == 1
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: improve demo_random

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: 
Changeset: r393:d791f50ecec8
Date: 2013-07-11 17:36 +0200
http://bitbucket.org/pypy/stmgc/changeset/d791f50ecec8/

Log:improve demo_random

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -137,7 +137,7 @@
 return x;
 }
 
-void push_roots()
+void push_roots(int with_cache)
 {
 int i;
 for (i = 0; i  td.num_roots; i++) {
@@ -145,19 +145,35 @@
 if (td.roots[i])
 stm_push_root(td.roots[i]);
 }
+
+if (with_cache) {
+stm_push_root(NULL);
+for (i = 0; i  CACHE_ENTRIES; i++) {
+if (td.writeable[i])
+stm_push_root((gcptr)td.writeable[i]);
+}
+}
 }
 
-__thread revision_t temp_cache[CACHE_ENTRIES];
-void pop_roots()
+void pop_roots(int with_cache)
 {
 int i;
+/* some objects may have changed positions */
+memset(td.writeable, 0, sizeof(td.writeable));
+
+if (with_cache) {
+gcptr obj = stm_pop_root();
+while (obj) {
+CACHE_AT(td.writeable, obj) = obj;
+obj = stm_pop_root();
+}
+}
+
 for (i = td.num_roots - 1; i = 0; i--) {
 if (td.roots[i])
 td.roots[i] = stm_pop_root();
 check(td.roots[i]);
 }
-/* some objects may have changed positions */
-memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 void del_root(int idx)
@@ -170,9 +186,9 @@
 nodeptr allocate_node()
 {
 nodeptr r;
-push_roots();
+push_roots(1);
 r = (nodeptr)stm_allocate(sizeof(struct node), GCTID_STRUCT_NODE);
-pop_roots();
+pop_roots(1);
 return r;
 }
 
@@ -354,22 +370,22 @@
 {
 int k = get_rand(100);
 if (k  10) {
-push_roots();
+push_roots(1);
 stm_push_root(p);
 stm_become_inevitable(fun);
 p = stm_pop_root();
-pop_roots();
+pop_roots(1);
 } 
 else if (k  40) {
-push_roots();
+push_roots(1);
 stmgc_minor_collect();
-pop_roots();
+pop_roots(1);
 p = NULL;
 } else if (k  41  DO_MAJOR_COLLECTS) {
 fprintf(stdout, major collect\n);
-push_roots();
+push_roots(1);
 stmgcpage_possibly_major_collect(1);
-pop_roots();
+pop_roots(1);
 p = NULL;
 }
 return p;
@@ -534,8 +550,9 @@
 p = id_hash_events(p, _r, _sr);
 else if (k  8)
 p = rare_events(p, _r, _sr);
-else if (get_rand(3) == 1) {
+else if (get_rand(20) == 1) {
 // transaction break
+fprintf(stdout, |);
 if (td.interruptible)
 return (gcptr)-1; // break current
 transaction_break();
@@ -547,7 +564,7 @@
 
 void transaction_break()
 {
-push_roots();
+push_roots(0);
 td.interruptible = 1;
 
 copy_roots(td.roots, td.roots_outside_perform, td.num_roots);
@@ -559,9 +576,9 @@
 copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
 
 td.interruptible = 0;
-pop_roots();
+pop_roots(0);
 
-memset(td.writeable, 0, sizeof(td.writeable));
+/* done by pop_roots() memset(td.writeable, 0, sizeof(td.writeable)); */
 }
 
 
@@ -576,8 +593,8 @@
 assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF);
 arg1 = stm_pop_root();
 assert(arg1 == NULL);
-pop_roots();
-push_roots();
+pop_roots(0);
+push_roots(0);
 stm_push_root(arg1);
 stm_push_root(end_marker);
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: hopefully in the right direction: now a single cond_call_stm_b because there may be many more variants in the future.

2013-07-11 Thread Raemi
Author: Remi Meier meier...@student.ethz.ch
Branch: stmgc-c4
Changeset: r65346:e1aa4591dc07
Date: 2013-07-11 18:12 +0200
http://bitbucket.org/pypy/pypy/changeset/e1aa4591dc07/

Log:hopefully in the right direction: now a single cond_call_stm_b
because there may be many more variants in the future.

diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -958,11 +958,8 @@
 def execute_cond_call_gc_wb_array(self, descr, a, b, c):
 py.test.skip(cond_call_gc_wb_array not supported)
 
-def execute_cond_call_stm_wb(self, descr, a):
-py.test.skip(cond_call_stm_wb not supported)
-
-def execute_cond_call_stm_rb(self, descr, a):
-py.test.skip(cond_call_stm_rb not supported)
+def execute_cond_call_stm_b(self, descr, a):
+py.test.skip(cond_call_stm_b not supported)
 
 def execute_keepalive(self, descr, x):
 pass
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -270,23 +270,43 @@
 rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address)
 return rffi.cast(lltype.Signed, rst_addr)
 
+class GcRootMap_stm(object):
+is_shadow_stack = False # XXX: should it have an is_stmgc?
 
-class WriteBarrierDescr(AbstractDescr):
+def __init__(self, gcdescr):
+pass
+
+def register_asm_addr(self, start, mark):
+pass
+
+def get_root_stack_top_addr(self):
+rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address)
+return rffi.cast(lltype.Signed, rst_addr)
+
+
+class BarrierDescr(AbstractDescr):
 def __init__(self, gc_ll_descr):
 self.llop1 = gc_ll_descr.llop1
 
 self.returns_modified_object = False
-self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+self.FUNCPTR = lltype.Ptr(lltype.FuncType(
 [llmemory.Address], lltype.Void))
 
-self.fielddescr_tid = gc_ll_descr.fielddescr_tid
 self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
 self.HDRPTR = gc_ll_descr.HDRPTR
-#
+
+def repr_of_descr(self):
+raise NotImplementedError
+
+def __repr(self):
+raise NotImplementedError
+
+class WriteBarrierDescr(BarrierDescr):
+def __init__(self, gc_ll_descr):
+BarrierDescr.__init__(self, gc_ll_descr)
+self.fielddescr_tid = gc_ll_descr.fielddescr_tid
+
 GCClass = gc_ll_descr.GCClass
-if GCClass is None: # for tests
-return
-
 self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
 self.jit_wb_if_flag_byteofs, self.jit_wb_if_flag_singlebyte = (
 self.extract_flag_byte(self.jit_wb_if_flag))
@@ -325,14 +345,9 @@
 return (i, struct.unpack('b', value[i])[0])
 
 def get_barrier_funcptr(self, returns_modified_object):
-assert returns_modified_object == self.returns_modified_object
-llop1 = self.llop1
-if returns_modified_object:
-funcptr = self.wb_failing_case_ptr
-else:
-FUNCTYPE = self.WB_FUNCPTR
-funcptr = llop1.get_write_barrier_failing_case(FUNCTYPE)
-return funcptr
+assert not returns_modified_object
+FUNCTYPE = self.FUNCPTR
+return llop1.get_write_barrier_failing_case(FUNCTYPE)
 
 def get_write_barrier_fn(self, cpu, returns_modified_object):
 # must pass in 'self.returns_modified_object', to make sure that
@@ -343,16 +358,13 @@
 
 def get_write_barrier_from_array_fn(self, cpu):
 # returns a function with arguments [array, index, newvalue]
-assert not self.returns_modified_object
 llop1 = self.llop1
 funcptr = llop1.get_write_barrier_from_array_failing_case(
-self.WB_FUNCPTR)
+self.FUNCPTR)
 funcaddr = llmemory.cast_ptr_to_adr(funcptr)
 return cpu.cast_adr_to_int(funcaddr)# this may return 0
 
 def has_write_barrier_from_array(self, cpu):
-if self.returns_modified_object:
-return False
 return self.get_write_barrier_from_array_fn(cpu) != 0
 
 def get_wb_slowpath(self, withcards, withfloats):
@@ -372,15 +384,11 @@
 # the GC, and call it immediately
 funcptr = self.get_barrier_funcptr(returns_modified_object)
 res = funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
-if returns_modified_object:
-return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
-else:
-if returns_modified_object:
-return gcref_struct
 
-class STMBarrierDescr(WriteBarrierDescr):
+
+class STMBarrierDescr(BarrierDescr):
 def __init__(self, gc_ll_descr, stmcat, cfunc_name):
-WriteBarrierDescr.__init__(self, gc_ll_descr)
+BarrierDescr.__init__(self, gc_ll_descr)

[pypy-commit] pypy stmgc-c4: remove R2W for now; introduce is_stm on GcRootMap

2013-07-12 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65374:add171e74fe2
Date: 2013-07-12 08:29 +0200
http://bitbucket.org/pypy/pypy/changeset/add171e74fe2/

Log:remove R2W for now; introduce is_stm on GcRootMap

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -250,6 +250,7 @@
 
 class GcRootMap_asmgcc(object):
 is_shadow_stack = False
+is_stm = False
 
 def __init__(self, gcdescr):
 pass
@@ -259,7 +260,8 @@
 
 class GcRootMap_shadowstack(object):
 is_shadow_stack = True
-
+is_stm = False
+
 def __init__(self, gcdescr):
 pass
 
@@ -271,8 +273,9 @@
 return rffi.cast(lltype.Signed, rst_addr)
 
 class GcRootMap_stm(object):
-is_shadow_stack = True # XXX: should it have an is_stmgc?
-
+is_shadow_stack = True
+is_stm = True
+
 def __init__(self, gcdescr):
 pass
 
@@ -535,7 +538,6 @@
 def _setup_barriers_for_stm(self):
 self.P2Rdescr = STMReadBarrierDescr(self, 'P2R')
 self.P2Wdescr = STMWriteBarrierDescr(self, 'P2W')
-self.R2Wdescr = STMWriteBarrierDescr(self, 'R2W')
 self.write_barrier_descr = wbdescr: do not use
 #
 @specialize.argtype(0)
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -34,7 +34,7 @@
 'P': {'R': self.gc_ll_descr.P2Rdescr,
   'W': self.gc_ll_descr.P2Wdescr,
  },
-'R': {'W': self.gc_ll_descr.R2Wdescr,
+'R': {'W': self.gc_ll_descr.P2Wdescr,
  },
 'W': {},
}
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -250,7 +250,7 @@
 cond_call_stm_b(p1, descr=P2Rdescr)
 i1 = getfield_gc(p1, descr=tydescr)
 i2 = int_add(i1, 1)
-cond_call_stm_b(p1, descr=R2Wdescr)
+cond_call_stm_b(p1, descr=P2Wdescr)
 setfield_gc(p1, i2, descr=tydescr)
 jump(p1)
 )
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1020,12 +1020,16 @@
 
 def _reload_frame_if_necessary(self, mc, align_stack=False):
 gcrootmap = self.cpu.gc_ll_descr.gcrootmap
-if gcrootmap:
-if gcrootmap.is_shadow_stack:
-rst = gcrootmap.get_root_stack_top_addr()
-mc.MOV(ecx, heap(rst))
-mc.MOV(ebp, mem(ecx, -WORD))
-wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
+if gcrootmap and gcrootmap.is_shadow_stack:
+rst = gcrootmap.get_root_stack_top_addr()
+mc.MOV(ecx, heap(rst))
+mc.MOV(ebp, mem(ecx, -WORD))
+
+if gcrootmap and gcrootmap.is_stm:
+wbdescr = self.cpu.gc_ll_descr.P2Wdescr
+else:
+wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
+
 if gcrootmap and wbdescr:
 # frame never uses card marking, so we enforce this is not
 # an array
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: break less stuff

2013-07-12 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65373:de492c4ceb35
Date: 2013-07-12 07:47 +0200
http://bitbucket.org/pypy/pypy/changeset/de492c4ceb35/

Log:break less stuff

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -271,7 +271,7 @@
 return rffi.cast(lltype.Signed, rst_addr)
 
 class GcRootMap_stm(object):
-is_shadow_stack = False # XXX: should it have an is_stmgc?
+is_shadow_stack = True # XXX: should it have an is_stmgc?
 
 def __init__(self, gcdescr):
 pass
@@ -289,9 +289,6 @@
 self.llop1 = gc_ll_descr.llop1
 
 self.returns_modified_object = False
-self.FUNCPTR = lltype.Ptr(lltype.FuncType(
-[llmemory.Address], lltype.Void))
-
 self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
 self.HDRPTR = gc_ll_descr.HDRPTR
 
@@ -305,6 +302,8 @@
 def __init__(self, gc_ll_descr):
 BarrierDescr.__init__(self, gc_ll_descr)
 self.fielddescr_tid = gc_ll_descr.fielddescr_tid
+self.FUNCPTR = lltype.Ptr(lltype.FuncType(
+[llmemory.Address], lltype.Void))
 
 GCClass = gc_ll_descr.GCClass
 self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
@@ -347,7 +346,7 @@
 def get_barrier_funcptr(self, returns_modified_object):
 assert not returns_modified_object
 FUNCTYPE = self.FUNCPTR
-return llop1.get_write_barrier_failing_case(FUNCTYPE)
+return self.llop1.get_write_barrier_failing_case(FUNCTYPE)
 
 def get_write_barrier_fn(self, cpu, returns_modified_object):
 # must pass in 'self.returns_modified_object', to make sure that
@@ -383,7 +382,7 @@
 # get a pointer to the 'remember_young_pointer' function from
 # the GC, and call it immediately
 funcptr = self.get_barrier_funcptr(returns_modified_object)
-res = funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
+funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
 
 
 class STMBarrierDescr(BarrierDescr):
@@ -391,13 +390,13 @@
 BarrierDescr.__init__(self, gc_ll_descr)
 self.stmcat = stmcat
 self.returns_modified_object = True
-self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
+self.B_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
 [llmemory.Address], llmemory.Address))
 
-self.wb_failing_case_ptr = rffi.llexternal(
+self.b_failing_case_ptr = rffi.llexternal(
 cfunc_name,
-self.WB_FUNCPTR_MOD.TO.ARGS,
-self.WB_FUNCPTR_MOD.TO.RESULT,
+self.B_FUNCPTR_MOD.TO.ARGS,
+self.B_FUNCPTR_MOD.TO.RESULT,
 sandboxsafe=True,
 _nowrapper=True)
 
@@ -409,7 +408,7 @@
 
 def get_barrier_funcptr(self, returns_modified_object):
 assert returns_modified_object
-return self.wb_failing_case_ptr
+return self.b_failing_case_ptr
 
 @specialize.arg(2)
 def _do_barrier(self, gcref_struct, returns_modified_object):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: progress on stm barriers (without fastpath) and GC without malloc fastpaths (nursery)

2013-07-12 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65375:21bde4788254
Date: 2013-07-12 16:47 +0200
http://bitbucket.org/pypy/pypy/changeset/21bde4788254/

Log:progress on stm barriers (without fastpath) and GC without malloc
fastpaths (nursery)

diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -81,27 +81,34 @@
 self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
 self._build_failure_recovery(False, withfloats=False)
 self._build_failure_recovery(True, withfloats=False)
-self._build_wb_slowpath(False)
-self._build_wb_slowpath(True)
-self._build_wb_slowpath(False, for_frame=True)
+if gc_ll_descr.stm:
+descrs = [gc_ll_descr.P2Rdescr, gc_ll_descr.P2Wdescr]
+else:
+descrs = [gc_ll_descr.write_barrier_descr]
+for d in descrs:
+self._build_b_slowpath(d, False)
+self._build_b_slowpath(d, True)
+self._build_b_slowpath(d, False, for_frame=True)
 # only one of those
 self.build_frame_realloc_slowpath()
 if self.cpu.supports_floats:
 self._build_failure_recovery(False, withfloats=True)
 self._build_failure_recovery(True, withfloats=True)
-self._build_wb_slowpath(False, withfloats=True)
-self._build_wb_slowpath(True, withfloats=True)
+for d in descrs:
+self._build_b_slowpath(d, False, withfloats=True)
+self._build_b_slowpath(d, True, withfloats=True)
 self._build_propagate_exception_path()
+
 if gc_ll_descr.get_malloc_slowpath_addr() is not None:
 # generate few slowpaths for various cases
 self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed')
 self.malloc_slowpath_varsize = self._build_malloc_slowpath(
 kind='var')
-if hasattr(gc_ll_descr, 'malloc_str'):
+if gc_ll_descr.get_malloc_slowpath_addr() is not None and 
hasattr(gc_ll_descr, 'malloc_str'):
 self.malloc_slowpath_str = self._build_malloc_slowpath(kind='str')
 else:
 self.malloc_slowpath_str = None
-if hasattr(gc_ll_descr, 'malloc_unicode'):
+if gc_ll_descr.get_malloc_slowpath_addr() is not None and 
hasattr(gc_ll_descr, 'malloc_unicode'):
 self.malloc_slowpath_unicode = self._build_malloc_slowpath(
 kind='unicode')
 else:
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -294,12 +294,42 @@
 self.returns_modified_object = False
 self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
 self.HDRPTR = gc_ll_descr.HDRPTR
+self.b_slowpath = [0, 0, 0, 0]
 
 def repr_of_descr(self):
 raise NotImplementedError
 
 def __repr(self):
 raise NotImplementedError
+
+def get_b_slowpath(self, num):
+return self.b_slowpath[num]
+
+def set_b_slowpath(self, num, addr):
+self.b_slowpath[num] = addr
+
+def get_barrier_funcptr(self, returns_modified_object):
+raise NotImplementedError
+
+def get_barrier_fn(self, cpu, returns_modified_object):
+# must pass in 'self.returns_modified_object', to make sure that
+# the callers are fixed for this case
+funcptr = self.get_barrier_funcptr(returns_modified_object)
+funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+return cpu.cast_adr_to_int(funcaddr)
+
+def get_barrier_from_array_fn(self, cpu):
+# returns a function with arguments [array, index, newvalue]
+llop1 = self.llop1
+funcptr = llop1.get_write_barrier_from_array_failing_case(
+self.FUNCPTR)
+funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+return cpu.cast_adr_to_int(funcaddr)# this may return 0
+
+def has_barrier_from_array(self, cpu):
+return self.get_barrier_from_array_fn(cpu) != 0
+
+
 
 class WriteBarrierDescr(BarrierDescr):
 def __init__(self, gc_ll_descr):
@@ -325,8 +355,6 @@
 assert self.jit_wb_cards_set_singlebyte == -0x80
 else:
 self.jit_wb_cards_set = 0
-#
-self.wb_slowpath = [0, 0, 0, 0]
 
 def repr_of_descr(self):
 return 'wbdescr'
@@ -351,30 +379,6 @@
 FUNCTYPE = self.FUNCPTR
 return self.llop1.get_write_barrier_failing_case(FUNCTYPE)
 
-def get_write_barrier_fn(self, cpu, returns_modified_object):
-# must pass in 'self.returns_modified_object', to make sure that
-# the callers are fixed for this case
-funcptr = self.get_barrier_funcptr(returns_modified_object)
-funcaddr = llmemory.cast_ptr_to_adr(funcptr)
- 

[pypy-commit] pypy stmgc-c4: satisfy some tests

2013-07-15 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65401:d11b7c7058b0
Date: 2013-07-15 12:17 +0200
http://bitbucket.org/pypy/pypy/changeset/d11b7c7058b0/

Log:satisfy some tests

diff --git a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py 
b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
@@ -75,11 +75,18 @@
 from rpython.translator.c import genc
 #
 t = TranslationContext()
-t.config.translation.gc = gc
+gcrootfinder = kwds['gcrootfinder']
+if gcrootfinder == 'stm':
+t.config.translation.stm = True
+t.config.translation.gc = 'stmgc'
+else:
+t.config.translation.gc = gc
+#
 if gc != 'boehm':
 t.config.translation.gcremovetypeptr = True
 for name, value in kwds.items():
 setattr(t.config.translation, name, value)
+
 ann = t.buildannotator()
 ann.build_types(f, [s_list_of_strings], main_entry_point=True)
 t.buildrtyper().specialize()
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2188,7 +2188,7 @@
 operations = [
 ResOperation(rop.COND_CALL_GC_WB, [p0, ConstInt(0)], None,
  descr=WriteBarrierDescr()),
-ResOperation(rop.FINISH, [p0], None, descr=BasicFailDescr(1))
+ResOperation(rop.FINISH, [p0], None, descr=BasicFinalDescr(0))
 ]
 inputargs = [p0]
 looptoken = JitCellToken()
@@ -4246,10 +4246,9 @@
 class WBDescrForTests(AbstractDescr):
 returns_modified_object = False
 b_slowpath = (0, 0, 0, 0)
-def get_b_slowpath(self, c1, c2):
-return self.b_slowpath[c1+2*c2]
-def set_b_slowpath(self, c1, c2, addr):
-i = c1+2*c2
-self.b_slowpath = (self.b_slowpath[:i] + (addr,) +
-self.b_slowpath[i+1:])
+def get_b_slowpath(self, c1):
+return self.b_slowpath[c1]
+def set_b_slowpath(self, c1, addr):
+self.b_slowpath = (self.b_slowpath[:c1] + (addr,) +
+self.b_slowpath[c1+1:])
 
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1032,19 +1032,22 @@
 cb.emit_no_collect()
 
 def _reload_frame_if_necessary(self, mc, align_stack=False):
-gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+gc_ll_descr = self.cpu.gc_ll_descr
+gcrootmap = gc_ll_descr.gcrootmap
 if gcrootmap and gcrootmap.is_shadow_stack:
 rst = gcrootmap.get_root_stack_top_addr()
 mc.MOV(ecx, heap(rst))
 mc.MOV(ebp, mem(ecx, -WORD))
 
 if gcrootmap and gcrootmap.is_stm:
-wbdescr = self.cpu.gc_ll_descr.P2Wdescr
+if not hasattr(gc_ll_descr, 'P2Wdescr'):
+raise Exception(unreachable code)
+wbdescr = gc_ll_descr.P2Wdescr
 self._stm_barrier_fastpath(mc, wbdescr, [ebp], is_frame=True,
align_stack=align_stack)
 return
 
-wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
+wbdescr = gc_ll_descr.write_barrier_descr
 if gcrootmap and wbdescr:
 # frame never uses card marking, so we enforce this is not
 # an array
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -825,7 +825,7 @@
 
 def consider_call_malloc_nursery_varsize_frame(self, op):
 gc_ll_descr = self.assembler.cpu.gc_ll_descr
-assert gc_ll_descr.max_size_of_young_obj is not None
+assert gc_ll_descr.get_malloc_slowpath_addr() is not None
 # ^^^ if this returns None, don't translate the rest of this function
 #
 size_box = op.getarg(0)
@@ -850,10 +850,8 @@
 
 def consider_call_malloc_nursery_varsize(self, op):
 gc_ll_descr = self.assembler.cpu.gc_ll_descr
-assert gc_ll_descr.max_size_of_young_obj is not None
-# ^^^ if this returns None, don't translate the rest of this function
-#
-if not hasattr(gc_ll_descr, 'max_size_of_young_obj'):
+if not hasattr(gc_ll_descr, 'max_size_of_young_obj') \
+  or gc_ll_descr.max_size_of_young_obj is None:
 raise Exception(unreachable code)
 # for boehm, this function should never be called
 arraydescr = op.getdescr()
diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py 
b/rpython/jit/backend/x86/test/test_zrpy_gc.py
--- a/rpython/jit/backend/x86/test/test_zrpy_gc.py
+++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py
@@ -1,5 +1,9 

[pypy-commit] pypy stmgc-c4: forgot OP_STM_GET_ROOT_STACK_TOP in funcgen

2013-07-15 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65400:7a372f0f9000
Date: 2013-07-15 08:35 +0200
http://bitbucket.org/pypy/pypy/changeset/7a372f0f9000/

Log:forgot OP_STM_GET_ROOT_STACK_TOP in funcgen

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
@@ -591,6 +591,7 @@
 OP_STM_PTR_EQ   = _OP_STM
 OP_STM_PUSH_ROOT= _OP_STM
 OP_STM_POP_ROOT_INTO= _OP_STM
+OP_STM_GET_ROOT_STACK_TOP   = _OP_STM
 OP_STM_ALLOCATE = _OP_STM
 OP_STM_GET_TID  = _OP_STM
 OP_STM_HASH = _OP_STM
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy stmgc-c4: fix and add more tests

2013-07-15 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65402:586771804a5c
Date: 2013-07-15 16:16 +0200
http://bitbucket.org/pypy/pypy/changeset/586771804a5c/

Log:fix and add more tests

diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -315,6 +315,9 @@
 exc0, exc1 = None, None
 if descr is None:
 return
+
+if is_stm and withcards:
+return
 
 if not withcards:
 func = descr.get_barrier_fn(self.cpu, 
diff --git a/rpython/memory/gctransform/test/test_framework.py 
b/rpython/memory/gctransform/test/test_framework.py
--- a/rpython/memory/gctransform/test/test_framework.py
+++ b/rpython/memory/gctransform/test/test_framework.py
@@ -23,7 +23,7 @@
 class transformerclass(ShadowStackFrameworkGCTransformer):
 root_stack_depth = 100
 
-def test_framework_simple():
+def test_framework_simple(gc=minimark):
 def g(x):
 return x + 1
 class A(object):
@@ -37,7 +37,10 @@
 from rpython.translator.c.genc import CStandaloneBuilder
 
 t = rtype(entrypoint, [s_list_of_strings])
-t.config.translation.gc = minimark
+if gc == stmgc:
+t.config.translation.stm = True
+t.config.translation.gc = gc
+
 cbuild = CStandaloneBuilder(t, entrypoint, t.config,
 gcpolicy=FrameworkGcPolicy2)
 db = cbuild.generate_graphs_for_llinterp()
@@ -54,6 +57,9 @@
 
 assert res == 2
 
+def test_framework_simple_stm():
+test_framework_simple(stmgc)
+
 def test_cancollect():
 S = lltype.GcStruct('S', ('x', lltype.Signed))
 def g():
@@ -94,7 +100,7 @@
 gg = graphof(t, g)
 assert CollectAnalyzer(t).analyze_direct_call(gg)
 
-def test_no_collect():
+def test_no_collect(gc=minimark):
 from rpython.rlib import rgc
 from rpython.translator.c.genc import CStandaloneBuilder
 
@@ -109,12 +115,17 @@
 return g() + 2
 
 t = rtype(entrypoint, [s_list_of_strings])
-t.config.translation.gc = minimark
+if gc == stmgc:
+t.config.translation.stm = True
+t.config.translation.gc = gc
 cbuild = CStandaloneBuilder(t, entrypoint, t.config,
 gcpolicy=FrameworkGcPolicy2)
 db = cbuild.generate_graphs_for_llinterp()
 
-def test_no_collect_detection():
+def test_no_collect_stm():
+test_no_collect(stmgc)
+
+def test_no_collect_detection(gc=minimark):
 from rpython.rlib import rgc
 from rpython.translator.c.genc import CStandaloneBuilder
 
@@ -133,13 +144,18 @@
 return g() + 2
 
 t = rtype(entrypoint, [s_list_of_strings])
-t.config.translation.gc = minimark
+if gc == stmgc:
+t.config.translation.stm = True
+t.config.translation.gc = gc
 cbuild = CStandaloneBuilder(t, entrypoint, t.config,
 gcpolicy=FrameworkGcPolicy2)
 f = py.test.raises(Exception, cbuild.generate_graphs_for_llinterp)
 expected = 'no_collect' function can trigger collection: function g at 
 assert str(f.value).startswith(expected)
 
+def test_no_collect_detection_stm():
+test_no_collect_detection(stmgc)
+
 class WriteBarrierTransformer(ShadowStackFrameworkGCTransformer):
 clean_sets = {}
 GC_PARAMS = {}
diff --git a/rpython/rlib/rstack.py b/rpython/rlib/rstack.py
--- a/rpython/rlib/rstack.py
+++ b/rpython/rlib/rstack.py
@@ -20,10 +20,10 @@
 includes=['src/stack.h'],
 separate_module_files=[srcdir / 'stack.c', srcdir / 'threadlocal.c'])
 
-def llexternal(name, args, res, _callable=None):
+def llexternal(name, args, res, _callable=None, **kwds):
 return rffi.llexternal(name, args, res, compilation_info=compilation_info,
sandboxsafe=True, _nowrapper=True,
-   _callable=_callable)
+   _callable=_callable, **kwds)
 
 _stack_get_end = llexternal('LL_stack_get_end', [], lltype.Signed,
 lambda: 0)
@@ -34,7 +34,8 @@
 lambda frac: None)
 _stack_too_big_slowpath = llexternal('LL_stack_too_big_slowpath',
  [lltype.Signed], lltype.Char,
- lambda cur: '\x00')
+ lambda cur: '\x00',
+ transactionsafe=True)
 # the following is used by the JIT
 _stack_get_end_adr   = llexternal('LL_stack_get_end_adr',   [], lltype.Signed)
 _stack_get_length_adr= llexternal('LL_stack_get_length_adr',[], lltype.Signed)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: fix one bug and use a big stub in case it is also needed as the h_original of an object

2013-07-15 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: 
Changeset: r399:6d83a39b28cf
Date: 2013-07-15 17:16 +0200
http://bitbucket.org/pypy/stmgc/changeset/6d83a39b28cf/

Log:fix one bug and use a big stub in case it is also needed as the
h_original of an object

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -75,7 +75,7 @@
 // helper functions
 int classify(gcptr p);
 void check(gcptr p);
-
+int in_nursery(gcptr obj);
 static int is_private(gcptr P)
 {
   return (P-h_revision == stm_private_rev_num) ||
@@ -226,8 +226,7 @@
 if (p-h_original  !(p-h_tid  GCFLAG_PREBUILT_ORIGINAL)) {
 // must point to valid old object
 gcptr id = (gcptr)p-h_original;
-assert(id-h_tid  GCFLAG_OLD);
-check_not_free(id);
+assert(!in_nursery(id));
 #ifdef _GC_DEBUG
 if (!is_shared_prebuilt(id)  !(id-h_tid  GCFLAG_PREBUILT))
 assert(!is_free_old(id));
diff --git a/c4/extra.c b/c4/extra.c
--- a/c4/extra.c
+++ b/c4/extra.c
@@ -107,10 +107,12 @@
 else {
 /* must create shadow original object XXX: or use
backup, if exists */
-
-/* XXX use stmgcpage_malloc() directly, we don't need to copy
- * the contents yet */
-gcptr O = stmgc_duplicate_old(p);
+gcptr O = (gcptr)stmgcpage_malloc(stmgc_size(p));
+memcpy(O, p, stmgc_size(p)); /* at least major collections
+  depend on some content of id_copy.
+  remove after fixing that XXX */
+O-h_tid |= GCFLAG_OLD;
+
 p-h_original = (revision_t)O;
 p-h_tid |= GCFLAG_HAS_ID;
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -39,7 +39,21 @@
 goto done;
 
  not_found:
-stub = stm_stub_malloc(sd-foreign_pd);
+if (!obj-h_original  !(obj-h_tid  GCFLAG_OLD)) {
+/* There shouldn't be a public, young object without
+   a h_original. But there can be priv/protected ones.
+   We have a young protected copy without an h_original
+   The stub we allocate will be the h_original, but
+   it must be big enough to be copied over by a major
+   collection later. */
+assert(!(obj-h_tid  GCFLAG_PUBLIC));
+
+stub = (gcptr)stmgcpage_malloc(stmgc_size(obj));
+STUB_THREAD(stub) = sd-foreign_pd;
+}
+else {
+stub = stm_stub_malloc(sd-foreign_pd);
+}
 stub-h_tid = (obj-h_tid  STM_USER_TID_MASK) | GCFLAG_PUBLIC
| GCFLAG_STUB
| GCFLAG_OLD;
@@ -51,10 +65,9 @@
 stub-h_original = (revision_t)obj;
 }
 else {
-/* There shouldn't be a public, young object without
-   a h_original. But there can be protected ones. */
-assert(!(obj-h_tid  GCFLAG_PUBLIC));
-obj-h_original = (revision_t)stub;
+/* this is the big-stub case described above */
+obj-h_original = (revision_t)stub; 
+stub-h_original = 0;   /* stub_malloc does not set to 0... */
 if (obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED) {
 ((gcptr)obj-h_revision)-h_original = (revision_t)stub;
 }
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original2: new approach doing the work of copying over h_original in visit()

2013-07-16 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: copy-over-original2
Changeset: r401:7c2e94ae8bf1
Date: 2013-07-16 13:33 +0200
http://bitbucket.org/pypy/stmgc/changeset/7c2e94ae8bf1/

Log:new approach doing the work of copying over h_original in visit()

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -945,6 +945,7 @@
   revision_t my_lock = d-my_lock;
   wlog_t *item;
 
+  dprintf((acquire_locks\n));
   assert(!stm_has_got_any_lock(d));
   assert(d-public_descriptor-stolen_objects.size == 0);
 
@@ -957,6 +958,7 @@
   revision_t v;
 retry:
   assert(R-h_tid  GCFLAG_PUBLIC);
+  assert(R-h_tid  GCFLAG_PUBLIC_TO_PRIVATE);
   v = ACCESS_ONCE(R-h_revision);
   if (IS_POINTER(v)) /* has a more recent revision */
 {
@@ -989,7 +991,7 @@
 static void CancelLocks(struct tx_descriptor *d)
 {
   wlog_t *item;
-
+  dprintf((cancel_locks\n));
   if (!g2l_any_entry(d-public_to_private))
 return;
 
@@ -1257,7 +1259,7 @@
   revision_t cur_time;
   struct tx_descriptor *d = thread_descriptor;
   assert(d-active = 1);
-
+  dprintf((CommitTransaction(%p)\n, d));
   spinlock_acquire(d-public_descriptor-collection_lock, 'C');  /*committing*/
   if (d-public_descriptor-stolen_objects.size != 0)
 stm_normalize_stolen_objects(d);
@@ -1341,6 +1343,7 @@
   d-active = 2;
   d-reads_size_limit_nonatomic = 0;
   update_reads_size_limit(d);
+  dprintf((make_inevitable(%p)\n, d));
 }
 
 static revision_t acquire_inev_mutex_and_mark_global_cur_time(
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -223,6 +223,7 @@
 id_copy-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
 /* see fix_outdated() */
 id_copy-h_tid |= GCFLAG_VISITED;
+assert(id_copy-h_tid  GCFLAG_OLD);
 
 /* XXX: may not always need tracing? */
 if (!(id_copy-h_tid  GCFLAG_STUB))
@@ -236,6 +237,55 @@
 }
 }
 
+static gcptr copy_over_original(gcptr obj)
+{
+assert(!(obj-h_tid  GCFLAG_VISITED));
+assert(!(obj-h_tid  GCFLAG_STUB));
+
+if (obj-h_tid  GCFLAG_PUBLIC /* XXX: required? */
+ !(obj-h_tid  GCFLAG_PREBUILT_ORIGINAL)
+ obj-h_original) {
+
+gcptr id_copy = (gcptr)obj-h_original;
+assert(!(id_copy-h_revision  1)); /* not head-revision itself */
+if (!(id_copy-h_tid  GCFLAG_PUBLIC))
+assert(0);
+/* return NULL; *//* could be priv_from_protected with
+   where backup is stolen and its h-original
+   points to it. */
+
+assert(stmgc_size(id_copy) == stmgc_size(obj));
+/* prehash may be specific hash value for prebuilts, or 0 */
+revision_t prehash = id_copy-h_original;
+assert(IMPLIES(prehash, id_copy-h_tid  GCFLAG_PREBUILT_ORIGINAL));
+/* old_tid may have prebuilt_original flags that should not be lost */
+revision_t old_tid = id_copy-h_tid;
+
+memcpy(id_copy, obj, stmgc_size(obj));
+assert(!((id_copy-h_tid ^ old_tid)
+  (GCFLAG_BACKUP_COPY //| GCFLAG_STUB, id_copy may be stub
+| GCFLAG_PUBLIC | GCFLAG_HAS_ID
+| GCFLAG_PRIVATE_FROM_PROTECTED)));
+id_copy-h_original = prehash;
+id_copy-h_tid = old_tid  ~GCFLAG_VISITED; /* will be visited next */
+
+dprintf((copy %p over %p\n, obj, id_copy));
+
+/* for those visiting later: */
+obj-h_revision = (revision_t)id_copy;
+
+/* mark as not old for transactions to fix their
+   public_to_private. Otherwise, inevitable transactions
+   would think their public obj was modified (also for
+   other transactions, but they can abort) */
+obj-h_tid = ~GCFLAG_OLD;
+
+return id_copy;
+}
+
+return NULL;
+}
+
 static void visit(gcptr *pobj)
 {
 gcptr obj = *pobj;
@@ -248,7 +298,26 @@
 assert(!(obj-h_tid  GCFLAG_STUB));
 if (!(obj-h_tid  GCFLAG_VISITED)) {
 obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;  /* see fix_outdated() */
+
+gcptr next = copy_over_original(obj);
+if (next) {
+revision_t loc = (revision_t)pobj - offsetof(struct 
stm_object_s,
+ h_revision);
+if ((gcptr)loc != next)
+/* we don't want to set h_revision of 'next' to
+   'next' itself, it was already set by 
+   copy_over_original to a global head revision */
+*pobj = next;
+obj = next;
+
+assert(obj-h_revision  1);
+assert(!(obj-h_tid  GCFLAG_VISITED));
+goto restart;
+}
+
 obj-h_tid |= GCFLAG_VISITED;
+assert(obj-h_tid  GCFLAG_OLD);
+
 gcptrlist_insert(objects_to_trace, obj);
 
 keep_original_alive(obj);
@@ 

[pypy-commit] stmgc copy-over-original2: uncomment jumping forward in visit() again

2013-07-16 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: copy-over-original2
Changeset: r403:7c66774a3b43
Date: 2013-07-16 14:40 +0200
http://bitbucket.org/pypy/stmgc/changeset/7c66774a3b43/

Log:uncomment jumping forward in visit() again

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -354,14 +354,14 @@
 }
 }
 
-/* if (!(obj-h_revision  3)) { */
-/* /\* obj is neither a stub nor a most recent revision: */
-/*completely ignore obj-h_revision *\/ */
+if (!(obj-h_revision  3)) {
+/* obj is neither a stub nor a most recent revision:
+   completely ignore obj-h_revision */
 
-/* obj = (gcptr)obj-h_revision; */
-/* assert(obj-h_tid  GCFLAG_PUBLIC); */
-/* prev_obj-h_revision = (revision_t)obj; */
-/* } */
+obj = (gcptr)obj-h_revision;
+assert(obj-h_tid  GCFLAG_PUBLIC);
+prev_obj-h_revision = (revision_t)obj;
+}
 *pobj = obj;
 goto restart;
 }
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original2: update comment

2013-07-16 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: copy-over-original2
Changeset: r402:a127a39f6967
Date: 2013-07-16 14:29 +0200
http://bitbucket.org/pypy/stmgc/changeset/a127a39f6967/

Log:update comment

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -637,6 +637,7 @@
 assert(!(obj-h_tid  GCFLAG_STUB));
 
 if (!(obj-h_tid  GCFLAG_OLD)) {
+assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
 obj = (gcptr)obj-h_revision;
 items[i] = obj;
 }
@@ -650,9 +651,7 @@
 assert(IS_POINTER(obj-h_revision));
 obj = (gcptr)obj-h_revision;
 
-/* backup copies will never be candidates for copy over
-   prebuilts, because there is always the priv-from-prot
-   object inbetween */
+/* the backup-ptr should already be updated: */
 assert(obj-h_tid  GCFLAG_OLD);
 }
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original2: use NURSERY_MOVED instead of ~OLD when copying an object over its original during major collections

2013-07-16 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: copy-over-original2
Changeset: r404:74ae9fa5621f
Date: 2013-07-16 14:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/74ae9fa5621f/

Log:use NURSERY_MOVED instead of ~OLD when copying an object over its
original during major collections

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -223,7 +223,7 @@
 id_copy-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;
 /* see fix_outdated() */
 id_copy-h_tid |= GCFLAG_VISITED;
-assert(id_copy-h_tid  GCFLAG_OLD);
+assert(!(id_copy-h_tid  GCFLAG_NURSERY_MOVED));
 
 /* XXX: may not always need tracing? */
 if (!(id_copy-h_tid  GCFLAG_STUB))
@@ -274,11 +274,11 @@
 /* for those visiting later: */
 obj-h_revision = (revision_t)id_copy;
 
-/* mark as not old for transactions to fix their
+/* mark as MOVED for transactions to fix their
public_to_private. Otherwise, inevitable transactions
would think their public obj was modified (also for
other transactions, but they can abort) */
-obj-h_tid = ~GCFLAG_OLD;
+obj-h_tid |= GCFLAG_NURSERY_MOVED;
 
 return id_copy;
 }
@@ -316,7 +316,7 @@
 }
 
 obj-h_tid |= GCFLAG_VISITED;
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 
 gcptrlist_insert(objects_to_trace, obj);
 
@@ -341,7 +341,7 @@
 obj = (gcptr)(obj-h_revision - 2);
 if (!(obj-h_tid  GCFLAG_PUBLIC)) {
 prev_obj-h_tid |= GCFLAG_VISITED;
-assert(prev_obj-h_tid  GCFLAG_OLD);
+assert(!(prev_obj-h_tid  GCFLAG_NURSERY_MOVED));
 
 keep_original_alive(prev_obj);
 
@@ -385,10 +385,10 @@
 }
 
 obj-h_tid |= GCFLAG_VISITED;
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 assert(!(obj-h_tid  GCFLAG_STUB));
 
-if (B-h_tid  GCFLAG_OLD) {
+if (!(B-h_tid  GCFLAG_NURSERY_MOVED)) {
 B-h_tid |= GCFLAG_VISITED;
 assert(!(B-h_tid  GCFLAG_STUB));
 gcptrlist_insert2(objects_to_trace, obj, B);
@@ -418,7 +418,7 @@
 if (!(obj-h_tid  GCFLAG_VISITED)) {
 obj-h_tid = ~GCFLAG_PUBLIC_TO_PRIVATE;  /* see fix_outdated() */
 obj-h_tid |= GCFLAG_VISITED;
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 gcptrlist_insert(objects_to_trace, obj);
 
 if (IS_POINTER(obj-h_revision)) {
@@ -516,7 +516,7 @@
 G2L_LOOP_FORWARD(d-public_to_private, item) {
 gcptr R = item-addr;
 gcptr L = item-val;
-if (!(R-h_tid  GCFLAG_OLD)) {
+if (R-h_tid  GCFLAG_NURSERY_MOVED) {
 /* R was copied over its original */
 gcptr new_R = (gcptr)R-h_original;
 /* gcptrlist_insert(objects_to_trace, new_R); */
@@ -600,7 +600,7 @@
 gcptr obj = items[i];
 assert(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED);
 /* we don't copy private / protected objects over prebuilts (yet) */
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 
 if (!(obj-h_tid  GCFLAG_VISITED)) {
 /* forget 'obj' */
@@ -615,7 +615,7 @@
 items = d-old_objects_to_trace.items;
 for (i = d-old_objects_to_trace.size - 1; i = 0; i--) {
 gcptr obj = items[i];
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 assert(obj-h_tid  GCFLAG_VISITED);
 }
 #endif
@@ -636,7 +636,7 @@
 gcptr obj = items[i];
 assert(!(obj-h_tid  GCFLAG_STUB));
 
-if (!(obj-h_tid  GCFLAG_OLD)) {
+if (obj-h_tid  GCFLAG_NURSERY_MOVED) {
 assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
 obj = (gcptr)obj-h_revision;
 items[i] = obj;
@@ -652,7 +652,7 @@
 obj = (gcptr)obj-h_revision;
 
 /* the backup-ptr should already be updated: */
-assert(obj-h_tid  GCFLAG_OLD);
+assert(!(obj-h_tid  GCFLAG_NURSERY_MOVED));
 }
 
 revision_t v = obj-h_revision;
@@ -695,7 +695,7 @@
 G2L_LOOP_FORWARD(d-public_to_private, item) {
 assert(item-addr-h_tid  GCFLAG_VISITED);
 assert(item-val-h_tid  GCFLAG_VISITED);
-assert(item-addr-h_tid  GCFLAG_OLD);
+assert(!(item-addr-h_tid  GCFLAG_NURSERY_MOVED));
 assert(item-addr-h_tid  GCFLAG_PUBLIC);
 /* assert(is_private(item-val)); but in the other thread,
which becomes: */
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc copy-over-original2: rename GCFLAG_NURSERY_MOVED to GCFLAG_MOVED

2013-07-16 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: copy-over-original2
Changeset: r405:9a584030a9e6
Date: 2013-07-16 15:08 +0200
http://bitbucket.org/pypy/stmgc/changeset/9a584030a9e6/

Log:rename GCFLAG_NURSERY_MOVED to GCFLAG_MOVED

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -302,7 +302,7 @@
 }
 else {
 if (in_nursery(p)) {
-assert(p-h_tid  GCFLAG_NURSERY_MOVED);
+assert(p-h_tid  GCFLAG_MOVED);
 assert(!(p-h_revision  1));
 }
 return C_PUBLIC;
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -122,7 +122,7 @@
   gcptr P_prev = P;
   P = (gcptr)v;
   assert((P-h_tid  GCFLAG_PUBLIC) ||
- (P_prev-h_tid  GCFLAG_NURSERY_MOVED));
+ (P_prev-h_tid  GCFLAG_MOVED));
 
   v = ACCESS_ONCE(P-h_revision);
 
@@ -214,7 +214,7 @@
  add_in_recent_reads_cache:
   /* The risks are that the following assert fails, because the flag was
  added just now by a parallel thread during stealing... */
-  /*assert(!(P-h_tid  GCFLAG_NURSERY_MOVED));*/
+  /*assert(!(P-h_tid  GCFLAG_MOVED));*/
   fxcache_add(d-recent_reads_cache, P);
   return P;
 
@@ -257,7 +257,7 @@
*/
   if (P-h_tid  GCFLAG_PUBLIC)
 {
-  if (P-h_tid  GCFLAG_NURSERY_MOVED)
+  if (P-h_tid  GCFLAG_MOVED)
 {
   P = (gcptr)P-h_revision;
   assert(P-h_tid  GCFLAG_PUBLIC);
@@ -389,7 +389,7 @@
 
   while (v = P-h_revision, IS_POINTER(v))
 {
-  if (P-h_tid  GCFLAG_NURSERY_MOVED)
+  if (P-h_tid  GCFLAG_MOVED)
 dprintf((nursery_moved ));
 
   if (v  2)
@@ -486,7 +486,7 @@
 static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R)
 {
   assert(R-h_tid  GCFLAG_PUBLIC);
-  assert(!(R-h_tid  GCFLAG_NURSERY_MOVED));
+  assert(!(R-h_tid  GCFLAG_MOVED));
 
 #ifdef _GC_DEBUG
   wlog_t *entry;
@@ -581,7 +581,7 @@
  Add R into the list 'public_with_young_copy', unless W is
  actually an old object, in which case we need to record W.
   */
-  if (R-h_tid  GCFLAG_NURSERY_MOVED)
+  if (R-h_tid  GCFLAG_MOVED)
 {
   /* Bah, the object turned into this kind of stub, possibly
  while we were waiting for the collection_lock, because it
@@ -671,8 +671,8 @@
   continue;
 }
 }
-  else if ((R-h_tid  (GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED))
-== (GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED))
+  else if ((R-h_tid  (GCFLAG_PUBLIC | GCFLAG_MOVED))
+== (GCFLAG_PUBLIC | GCFLAG_MOVED))
 {
   /* such an object is identical to the one it points to
(stolen protected young object with h_revision pointing
@@ -1084,7 +1084,7 @@
   assert(!(L-h_tid  GCFLAG_VISITED));
   assert(!(L-h_tid  GCFLAG_PUBLIC_TO_PRIVATE));
   assert(!(L-h_tid  GCFLAG_PREBUILT_ORIGINAL));
-  assert(!(L-h_tid  GCFLAG_NURSERY_MOVED));
+  assert(!(L-h_tid  GCFLAG_MOVED));
   assert(L-h_revision != localrev);   /* modified by AcquireLocks() */
 
 #ifdef DUMP_EXTRA
@@ -1131,7 +1131,7 @@
 
   assert(R-h_tid  GCFLAG_PUBLIC);
   assert(R-h_tid  GCFLAG_PUBLIC_TO_PRIVATE);
-  assert(!(R-h_tid  GCFLAG_NURSERY_MOVED));
+  assert(!(R-h_tid  GCFLAG_MOVED));
   assert(R-h_revision != localrev);
 
 #ifdef DUMP_EXTRA
@@ -1226,7 +1226,7 @@
   assert(!(B-h_tid  GCFLAG_BACKUP_COPY));
   P-h_tid |= GCFLAG_PUBLIC;
   assert(!(P-h_tid  GCFLAG_HAS_ID));
-  if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_NURSERY_MOVED;
+  if (!(P-h_tid  GCFLAG_OLD)) P-h_tid |= GCFLAG_MOVED;
   /* P becomes a public outdated object.  It may create an
  exception documented in doc-objects.txt: a public but young
  object.  It's still fine because it should only be seen by
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -46,7 +46,7 @@
  * the list 'old_objects_to_trace'; it is set again at the next minor
  * collection.
  *
- * GCFLAG_NURSERY_MOVED is used temporarily during minor collections.
+ * GCFLAG_MOVED is used temporarily during minor/major collections.
  *
  * GCFLAG_STUB is set for debugging on stub objects made by stealing or
  * by major collections.  'p_stub-h_revision' might be a value
@@ -67,7 +67,7 @@
 static const revision_t GCFLAG_PREBUILT_ORIGINAL  = STM_FIRST_GCFLAG  3;
 static const revision_t GCFLAG_PUBLIC_TO_PRIVATE  = STM_FIRST_GCFLAG  4;
 // in stmgc.h:  GCFLAG_WRITE_BARRIER  = STM_FIRST_GCFLAG  5;
-static const revision_t GCFLAG_NURSERY_MOVED  = STM_FIRST_GCFLAG  6;
+static const revision_t GCFLAG_MOVED  = STM_FIRST_GCFLAG  6;
 static const revision_t GCFLAG_BACKUP_COPY  /*debug*/ = STM_FIRST_GCFLAG  7;
 static const revision_t GCFLAG_STUB /*debug*/ = 

[pypy-commit] pypy stmgc-c4: fighting layers to make it work

2013-07-17 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65424:8a3c2efecdca
Date: 2013-07-17 11:22 +0200
http://bitbucket.org/pypy/pypy/changeset/8a3c2efecdca/

Log:fighting layers to make it work

diff --git a/rpython/jit/backend/arm/regalloc.py 
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -628,7 +628,7 @@
 descr = op.getdescr()
 fail_descr = cast_instance_to_gcref(descr)
 # we know it does not move, but well
-rgc._make_sure_does_not_move(fail_descr)
+fail_descr = rgc._make_sure_does_not_move(fail_descr)
 fail_descr = rffi.cast(lltype.Signed, fail_descr)
 if op.numargs() == 1:
 loc = self.make_sure_var_in_reg(op.getarg(0))
diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -222,7 +222,7 @@
 raise AssertionError(kind)
 
 gcref = cast_instance_to_gcref(value)
-rgc._make_sure_does_not_move(gcref)
+gcref = rgc._make_sure_does_not_move(gcref)
 value = rffi.cast(lltype.Signed, gcref)
 je_location = self._call_assembler_check_descr(value, tmploc)
 #
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -107,9 +107,12 @@
 gcrefs_output_list.append(new_p)
 
 if op.is_guard() or op.getopnum() == rop.FINISH:
-llref = cast_instance_to_gcref(op.getdescr())
+# the only ops with descrs that get recorded in a trace
+from rpython.jit.metainterp.history import AbstractDescr
+descr = op.getdescr()
+llref = cast_instance_to_gcref(descr)
 new_llref = rgc._make_sure_does_not_move(llref)
-new_d = rgc.try_cast_gcref_to_instance(llref.__class__, new_llref)
+new_d = rgc.try_cast_gcref_to_instance(AbstractDescr, new_llref)
 op.setdescr(new_d)
 gcrefs_output_list.append(new_llref)
 
@@ -298,7 +301,7 @@
 self.returns_modified_object = False
 self.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
 self.HDRPTR = gc_ll_descr.HDRPTR
-self.b_slowpath = [0, 0, 0, 0]
+self.b_slowpath = [0, 0, 0, 0, 0]
 
 def repr_of_descr(self):
 raise NotImplementedError
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -368,7 +368,7 @@
 descr = op.getdescr()
 fail_descr = cast_instance_to_gcref(descr)
 # we know it does not move, but well
-rgc._make_sure_does_not_move(fail_descr)
+fail_descr = rgc._make_sure_does_not_move(fail_descr)
 fail_descr = rffi.cast(lltype.Signed, fail_descr)
 if op.numargs() == 1:
 loc = self.make_sure_var_in_reg(op.getarg(0))
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
@@ -65,21 +65,25 @@
 return llop.stm_get_tid(llgroup.HALFWORD, obj)
 
 def get_hdr_tid(self, addr):
-return llmemory.cast_adr_to_int(addr + self.H_TID)
+return llmemory.cast_adr_to_ptr(addr + self.H_TID, rffi.SIGNEDP)
 
 def get_hdr_revision(self, addr):
-return llmemory.cast_adr_to_int(addr + self.H_REVISION)
-
+return llmemory.cast_adr_to_ptr(addr + self.H_REVISION, rffi.SIGNEDP)
+
 def get_hdr_original(self, addr):
-return llmemory.cast_adr_to_int(addr + self.H_ORIGINAL)
+return llmemory.cast_adr_to_ptr(addr + self.H_ORIGINAL, rffi.SIGNEDP)
 
-def get_original_object(self, obj):
-if bool(self.get_hdr_tid(obj)  GCFLAG_PREBUILT_ORIGINAL):
+def get_original_copy(self, obj):
+addr = llmemory.cast_ptr_to_adr(obj)
+if bool(self.get_hdr_tid(addr)[0]  GCFLAG_PREBUILT_ORIGINAL):
 return obj
-orig = self.get_hdr_original(obj)
+#
+orig = self.get_hdr_original(addr)[0]
 if orig == 0:
 return obj
-return llmemory.cast_int_to_adr(orig)
+#
+return  llmemory.cast_adr_to_ptr(llmemory.cast_int_to_adr(orig), 
+ llmemory.GCREF)
 
 def init_gc_object_immortal(self, addr, typeid16, flags=0):
 assert flags == 0
@@ -117,7 +121,7 @@
 def can_move(self, obj):
 Means the reference will stay valid, except if not
 seen by the GC, then it can get collected.
-tid = self.get_hdr_tid(obj)
+tid = self.get_hdr_tid(obj)[0]
 if bool(tid  GCFLAG_OLD):
 return False
 return True
diff --git 

[pypy-commit] pypy stmgc-c4: prepare for fastpath for ptr_eq and fix slowpath of stm-barriers

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: stmgc-c4
Changeset: r65454:ef39cd09001d
Date: 2013-07-18 08:30 +0200
http://bitbucket.org/pypy/pypy/changeset/ef39cd09001d/

Log:prepare for fastpath for ptr_eq and fix slowpath of stm-barriers

diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -89,6 +89,11 @@
 self._build_b_slowpath(d, False)
 self._build_b_slowpath(d, True)
 self._build_b_slowpath(d, False, for_frame=True)
+# only for stm:
+if hasattr(gc_ll_descr, 'stm_ptr_eq_FUNCPTR'):
+self._build_ptr_eq_slowpath()
+else:
+self.ptr_eq_slowpath = None
 # only one of those
 self.build_frame_realloc_slowpath()
 if self.cpu.supports_floats:
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -110,6 +110,8 @@
 # the only ops with descrs that get recorded in a trace
 from rpython.jit.metainterp.history import AbstractDescr
 descr = op.getdescr()
+if not we_are_translated() and descr is None:
+return
 llref = cast_instance_to_gcref(descr)
 new_llref = rgc._make_sure_does_not_move(llref)
 new_d = rgc.try_cast_gcref_to_instance(AbstractDescr, new_llref)
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -173,12 +173,4 @@
 return isinstance(box, ConstPtr) and not box.value
 
 def handle_ptr_eq(self, op):
-if self._is_null(op.getarg(0)) or self._is_null(op.getarg(1)):
-self.newops.append(op)
-return
-args = op.getarglist()
-result = op.result
-if op.getopnum() in (rop.PTR_EQ, rop.INSTANCE_PTR_EQ):
-self._do_stm_call('stm_ptr_eq', args, result)
-else:
-self._do_stm_call('stm_ptr_ne', args, result)
+self.newops.append(op)
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -517,7 +517,7 @@
 jump(i1)
 , 
 [p1, p2]
-i1 = call(ConstClass(stm_ptr_eq), p1, p2, descr=stm_ptr_eq_descr)
+i1 = ptr_eq(p1, p2)
 jump(i1)
 )
 
@@ -528,7 +528,7 @@
 jump(i1)
 , 
 [p1, p2]
-i1 = call(ConstClass(stm_ptr_eq), p1, p2, descr=stm_ptr_eq_descr)
+i1 = instance_ptr_eq(p1, p2)
 jump(i1)
 )
 
@@ -539,7 +539,7 @@
 jump(i1)
 , 
 [p1, p2]
-i1 = call(ConstClass(stm_ptr_ne), p1, p2, descr=stm_ptr_ne_descr)
+i1 = ptr_ne(p1, p2)
 jump(i1)
 )
 
@@ -550,7 +550,7 @@
 jump(i1)
 , 
 [p1, p2]
-i1 = call(ConstClass(stm_ptr_ne), p1, p2, descr=stm_ptr_ne_descr)
+i1 = instance_ptr_ne(p1, p2)
 jump(i1)
 )
 
diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py
--- a/rpython/jit/backend/x86/arch.py
+++ b/rpython/jit/backend/x86/arch.py
@@ -21,6 +21,7 @@
 #|   scratch  |
 #|  space |
 #++== aligned to 16 bytes
+# STACK TOP
 
 # All the rest of the data is in a GC-managed variable-size frame.
 # This frame object's address is always stored in the register EBP/RBP.
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -309,6 +309,61 @@
 rawstart = mc.materialize(self.cpu.asmmemmgr, [])
 self.stack_check_slowpath = rawstart
 
+
+def _build_ptr_eq_slowpath(self):
+cpu = self.cpu
+is_stm = cpu.gc_ll_descr.stm
+assert is_stm
+
+func = cpu.gc_ll_descr.get_malloc_fn_addr('stm_ptr_eq')
+#
+# This builds a helper function called from the slow path of
+# ptr_eq/ne.  It must save all registers, and optionally
+# all XMM registers.  It takes a single argument just pushed
+# on the stack even on X86_64.  It must restore stack alignment
+# accordingly.
+mc = codebuf.MachineCodeBlockWrapper()
+#
+self._push_all_regs_to_frame(mc, [], withfloats=False,
+ callee_only=True)
+#
+if IS_X86_32:
+# ||val2|val1|retaddr|  growing-, || aligned 
+   

[pypy-commit] stmgc weakref: try to add weakrefs to demo_random.c

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r408:e203655b8773
Date: 2013-07-18 10:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/e203655b8773/

Log:try to add weakrefs to demo_random.c

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -25,27 +25,46 @@
 
 // SUPPORT
 #define GCTID_STRUCT_NODE 123
+#define GCTID_WEAKREF 122
+
+struct node;
+typedef struct node * nodeptr;
+struct weak_node {
+struct stm_object_s hdr;
+nodeptr node;
+};
+typedef struct weak_node * weaknodeptr;
+#define WEAKNODE_SIZE  sizeof(struct weak_node)
 
 struct node {
 struct stm_object_s hdr;
 long value;
 revision_t id;
 revision_t hash;
-struct node *next;
+nodeptr next;
+weaknodeptr weakref;
 };
-typedef struct node * nodeptr;
+
+
 
 size_t stmcb_size(gcptr ob)
 {
-assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
-return sizeof(struct node);
+if (stm_get_tid(ob) == GCTID_STRUCT_NODE)
+return sizeof(struct node);
+else if (stm_get_tid(ob) == GCTID_WEAKREF)
+return WEAKNODE_SIZE;
+assert(0);
 }
+
 void stmcb_trace(gcptr ob, void visit(gcptr *))
 {
 nodeptr n;
+if (stm_get_tid(ob) == GCTID_WEAKREF)
+return;
 assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
 n = (nodeptr)ob;
 visit((gcptr *)n-next);
+visit((gcptr *)n-weakref);
 }
 
 
@@ -105,6 +124,21 @@
 return (int)(rand_r(td.thread_seed) % (unsigned int)max);
 }
 
+gcptr get_random_root()
+{
+int num = get_rand(td.num_roots + 1);
+if (num == 0)
+return stm_thread_local_obj;
+else
+return td.roots[num - 1];
+}
+
+gcptr get_random_shared_root()
+{
+int num = get_rand(SHARED_ROOTS);
+return shared_roots[num];
+}
+
 void copy_roots(gcptr *from, gcptr *to, int num)
 {
 int i;
@@ -192,6 +226,27 @@
 return r;
 }
 
+
+weaknodeptr allocate_weaknodeptr(nodeptr to)
+{
+weaknodeptr w;
+push_roots(1);
+w = (weaknodeptr)stm_weakref_allocate(WEAKNODE_SIZE, GCTID_WEAKREF,
+  (gcptr)to);
+pop_roots(1);
+return w;
+}
+
+void set_weakref(nodeptr n, nodeptr to)
+{
+stm_push_root((gcptr)n);
+weaknodeptr w = allocate_weaknodeptr(to);
+n = (nodeptr)stm_pop_root();
+n = (nodeptr)stm_write_barrier((gcptr)n);
+n-weakref = w;
+dprintf((set_weakref %p - %p - %p\n, n, w, to));
+}
+
 int is_shared_prebuilt(gcptr p)
 {
 int i;
@@ -448,6 +503,46 @@
 return p;
 }
 
+gcptr weakref_events(gcptr p, gcptr _r, gcptr _sr)
+{
+nodeptr t;
+weaknodeptr w;
+gcptr ptrs[] = {_r, _sr};
+
+int i = get_rand(2);
+int k = get_rand(3);
+switch (k) {
+case 0: // check weakref
+t = (nodeptr)read_barrier(ptrs[i]);
+w = t-weakref;
+if(w) {
+if (w-node) {
+assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
+check((gcptr)w-node);
+return (gcptr)w-node;
+}
+else {
+t-weakref = NULL;
+}
+}
+p = NULL;
+break;
+case 1: // set weakref to something
+if (p)
+set_weakref((nodeptr)_r, (nodeptr)p);
+else
+set_weakref((nodeptr)_r, (nodeptr)get_random_root());
+p = NULL;
+break;
+case 2: // set weakref on shared roots
+set_weakref((nodeptr)_sr, (nodeptr)get_random_shared_root());
+p = NULL;
+break;
+}
+return p;
+}
+
+
 gcptr shared_roots_events(gcptr p, gcptr _r, gcptr _sr)
 {
 nodeptr w_sr;
@@ -462,7 +557,7 @@
 break;
 case 2:
 w_sr = (nodeptr)write_barrier(_sr);
-w_sr-next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)];
+w_sr-next = (nodeptr)get_random_shared_root();
 break;
 }
 return p;
@@ -527,18 +622,12 @@
 gcptr do_step(gcptr p)
 {
 gcptr _r, _sr;
-int num, k;
+int k;
 
-num = get_rand(td.num_roots+1);
-if (num == 0)
-_r = stm_thread_local_obj;
-else
-_r = td.roots[num - 1];
-
-num = get_rand(SHARED_ROOTS);
-_sr = shared_roots[num];
+_r = get_random_root();
+_sr = get_random_shared_root();
 
-k = get_rand(9);
+k = get_rand(11);
 check(p);
 assert(thread_descriptor-active);
 
@@ -550,6 +639,8 @@
 p = id_hash_events(p, _r, _sr);
 else if (k  8)
 p = rare_events(p, _r, _sr);
+else if (k  10)
+p = weakref_events(p, _r, _sr);
 else if (get_rand(20) == 1) {
 // transaction break
 fprintf(stdout, |);
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -5,11 +5,14 @@
 
 gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj)
 {
+stm_push_root(obj);
 gcptr weakref = stm_allocate(size, tid);
+obj = stm_pop_root();
 assert(!(weakref-h_tid  GCFLAG_OLD));   /* 'size' too big? */
 assert(stmgc_size(weakref) 

[pypy-commit] stmgc weakref: implementing immutables and trying to fix the stealing of weakrefs

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r409:1cf2347f286d
Date: 2013-07-18 14:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/1cf2347f286d/

Log:implementing immutables and trying to fix the stealing of weakrefs

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -516,8 +516,8 @@
 t = (nodeptr)read_barrier(ptrs[i]);
 w = t-weakref;
 if(w) {
+assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
 if (w-node) {
-assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
 check((gcptr)w-node);
 return (gcptr)w-node;
 }
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -545,6 +545,7 @@
 
 gcptr stm_WriteBarrier(gcptr P)
 {
+  assert(!(P-h_tid  GCFLAG_IMMUTABLE));
   if (is_private(P))
 {
   /* If we have GCFLAG_WRITE_BARRIER in P, then list it into
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -72,6 +72,8 @@
 static const revision_t GCFLAG_STUB /*debug*/ = STM_FIRST_GCFLAG  8;
 static const revision_t GCFLAG_PRIVATE_FROM_PROTECTED = STM_FIRST_GCFLAG  9;
 static const revision_t GCFLAG_HAS_ID = STM_FIRST_GCFLAG  10;
+static const revision_t GCFLAG_IMMUTABLE  = STM_FIRST_GCFLAG  11;
+
 
 /* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
 #define GCFLAG_PREBUILT  (GCFLAG_VISITED   | \
@@ -89,6 +91,8 @@
  BACKUP_COPY,   \
  STUB,  \
  PRIVATE_FROM_PROTECTED, \
+ HAS_ID, \
+ IMMUTABLE, \
  NULL }
 
 #define IS_POINTER(v)(!((v)  1))   /* even-valued number */
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -101,6 +101,13 @@
 return P;
 }
 
+gcptr stm_allocate_immutable(size_t size, unsigned long tid)
+{
+gcptr P = stm_allocate(size, tid);
+P-h_tid |= GCFLAG_IMMUTABLE;
+return P;
+}
+
 gcptr stmgc_duplicate(gcptr P)
 {
 size_t size = stmgc_size(P);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -21,9 +21,47 @@
 {
 gcptr stub, obj = *pobj;
 if (obj == NULL || (obj-h_tid  (GCFLAG_PUBLIC | GCFLAG_OLD)) ==
-(GCFLAG_PUBLIC | GCFLAG_OLD))
+ (GCFLAG_PUBLIC | GCFLAG_OLD))
 return;
 
+if (obj-h_tid  GCFLAG_IMMUTABLE) {
+assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+/* old or young protected! mark as PUBLIC */
+if (!(obj-h_tid  GCFLAG_PUBLIC)) {
+if (!(obj-h_tid  GCFLAG_OLD)) {
+gcptr O;
+
+if (obj-h_tid  GCFLAG_HAS_ID) {
+/* use id-copy for us */
+O = (gcptr)obj-h_original;
+obj-h_tid = ~GCFLAG_HAS_ID;
+stm_copy_to_old_id_copy(obj, O);
+O-h_original = 0;
+} else {
+O = stmgc_duplicate_old(obj);
+
+/* young and without original? */
+if (!(obj-h_original))
+obj-h_original = (revision_t)O;
+}
+obj-h_revision = (revision_t)O;
+
+O-h_tid |= GCFLAG_PUBLIC;
+obj-h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
+/* here it is fine if it stays in read caches because
+   the object is immutable anyway and there are no
+   write_barriers allowed. */
+
+dprintf((steal prot immutable - public: %p | %p\n, obj, O));
+stub = obj;
+goto done;
+}
+dprintf((prot immutable - public: %p\n, obj));
+obj-h_tid |= GCFLAG_PUBLIC;
+}
+return;
+}
+
 /* we use 'all_stubs', a dictionary, in order to try to avoid
duplicate stubs for the same object.  XXX maybe it would be
better to use a fast approximative cache that stays around for
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -29,6 +29,9 @@
 
 /* allocate an object out of the local nursery */
 gcptr stm_allocate(size_t size, unsigned long tid);
+/* allocate an object that is be immutable. it cannot be changed with
+   a stm_write_barrier() or after the next commit */
+gcptr stm_allocate_immutable(size_t size, unsigned long tid);
 
 /* returns a never changing hash for the object */
 revision_t stm_hash(gcptr);
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -6,7 +6,7 @@
 gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj)
 {
 stm_push_root(obj);
-gcptr weakref = stm_allocate(size, tid);
+gcptr weakref = stm_allocate_immutable(size, tid);
 obj = stm_pop_root();
 

[pypy-commit] stmgc weakref: typo that doesn't change much

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r410:212e6e027030
Date: 2013-07-18 14:49 +0200
http://bitbucket.org/pypy/stmgc/changeset/212e6e027030/

Log:typo that doesn't change much

diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -53,7 +53,7 @@
write_barriers allowed. */
 
 dprintf((steal prot immutable - public: %p | %p\n, obj, O));
-stub = obj;
+stub = O;
 goto done;
 }
 dprintf((prot immutable - public: %p\n, obj));
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc weakref: and there was a bug in demo_random

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r412:324c3f18bbad
Date: 2013-07-18 16:11 +0200
http://bitbucket.org/pypy/stmgc/changeset/324c3f18bbad/

Log:and there was a bug 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
@@ -506,7 +506,7 @@
 gcptr weakref_events(gcptr p, gcptr _r, gcptr _sr)
 {
 nodeptr t;
-weaknodeptr w;
+weaknodeptr w, ww;
 gcptr ptrs[] = {_r, _sr};
 
 int i = get_rand(2);
@@ -516,10 +516,11 @@
 t = (nodeptr)read_barrier(ptrs[i]);
 w = t-weakref;
 if(w) {
-assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
-if (w-node) {
-check((gcptr)w-node);
-return (gcptr)w-node;
+ww = stm_read_barrier(w);
+assert(stm_get_tid((gcptr)ww) == GCTID_WEAKREF);
+if (ww-node) {
+check((gcptr)ww-node);
+return (gcptr)ww-node;
 }
 else {
 t-weakref = NULL;
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -18,7 +18,6 @@
 
 
 /* Minor collection */
-
 static int is_in_nursery(struct tx_descriptor *d, gcptr obj)
 {
 return (d-nursery_base = (char*)obj  ((char*)obj)  d-nursery_end);
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc weakref: clean it up a bit

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r411:ff8c751610ca
Date: 2013-07-18 15:41 +0200
http://bitbucket.org/pypy/stmgc/changeset/ff8c751610ca/

Log:clean it up a bit

diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -26,39 +26,47 @@
 
 if (obj-h_tid  GCFLAG_IMMUTABLE) {
 assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
+if (obj-h_tid  GCFLAG_PUBLIC) {
+/* young public */
+assert(obj-h_tid  GCFLAG_NURSERY_MOVED);
+assert(IS_POINTER(obj-h_revision));
+stub = (gcptr)obj-h_revision;
+goto done;
+}
+
 /* old or young protected! mark as PUBLIC */
-if (!(obj-h_tid  GCFLAG_PUBLIC)) {
-if (!(obj-h_tid  GCFLAG_OLD)) {
-gcptr O;
+if (!(obj-h_tid  GCFLAG_OLD)) {
+/* young protected */
+gcptr O;
+
+if (obj-h_tid  GCFLAG_HAS_ID) {
+/* use id-copy for us */
+O = (gcptr)obj-h_original;
+obj-h_tid = ~GCFLAG_HAS_ID;
+stm_copy_to_old_id_copy(obj, O);
+O-h_original = 0;
+} else {
+O = stmgc_duplicate_old(obj);
 
-if (obj-h_tid  GCFLAG_HAS_ID) {
-/* use id-copy for us */
-O = (gcptr)obj-h_original;
-obj-h_tid = ~GCFLAG_HAS_ID;
-stm_copy_to_old_id_copy(obj, O);
-O-h_original = 0;
-} else {
-O = stmgc_duplicate_old(obj);
-
-/* young and without original? */
-if (!(obj-h_original))
-obj-h_original = (revision_t)O;
-}
-obj-h_revision = (revision_t)O;
-
-O-h_tid |= GCFLAG_PUBLIC;
-obj-h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
-/* here it is fine if it stays in read caches because
-   the object is immutable anyway and there are no
-   write_barriers allowed. */
-
-dprintf((steal prot immutable - public: %p | %p\n, obj, O));
-stub = O;
-goto done;
+/* young and without original? */
+if (!(obj-h_original))
+obj-h_original = (revision_t)O;
 }
-dprintf((prot immutable - public: %p\n, obj));
-obj-h_tid |= GCFLAG_PUBLIC;
+obj-h_revision = (revision_t)O;
+
+O-h_tid |= GCFLAG_PUBLIC;
+obj-h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
+/* here it is fine if it stays in read caches because
+   the object is immutable anyway and there are no
+   write_barriers allowed. */
+dprintf((steal prot immutable - public: %p - %p\n, obj, O));
+stub = O;
+goto done;
 }
+/* old protected: */
+dprintf((prot immutable - public: %p\n, obj));
+obj-h_tid |= GCFLAG_PUBLIC;
+
 return;
 }
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc weakref: add stm_dbg_get_hdr_str() that prints the flags and tid of an object

2013-07-18 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r414:560fad6b4f7f
Date: 2013-07-19 07:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/560fad6b4f7f/

Log:add stm_dbg_get_hdr_str() that prints the flags and tid of an object

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -516,7 +516,7 @@
 t = (nodeptr)read_barrier(ptrs[i]);
 w = t-weakref;
 if(w) {
-ww = stm_read_barrier(w);
+ww = (weaknodeptr)stm_read_barrier((gcptr)w);
 assert(stm_get_tid((gcptr)ww) == GCTID_WEAKREF);
 if (ww-node) {
 check((gcptr)ww-node);
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -6,6 +6,28 @@
  */
 #include stmimpl.h
 
+#ifdef _GC_DEBUG
+char tmp_buf[128];
+char* stm_dbg_get_hdr_str(gcptr obj)
+{
+char *cur;
+char *flags[] = GC_FLAG_NAMES;
+int i;
+
+i = 0;
+cur = tmp_buf;
+while (flags[i]) {
+if (obj-h_tid  (STM_FIRST_GCFLAG  i)) {
+cur += sprintf(cur, %s|, flags[i]);
+}
+i++;
+}
+cur += sprintf(cur, tid=%ld\n, stm_get_tid(obj));
+return tmp_buf;
+}
+#endif
+
+
 
 __thread struct tx_descriptor *thread_descriptor = NULL;
 
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -200,4 +200,7 @@
 void DescriptorInit(void);
 void DescriptorDone(void);
 
+#ifdef _GC_DEBUG
+char* stm_dbg_get_hdr_str(gcptr obj);
+#endif
 #endif  /* _ET_H */
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc weakref: more debug output

2013-07-19 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: weakref
Changeset: r418:983bb16c726a
Date: 2013-07-19 11:46 +0200
http://bitbucket.org/pypy/stmgc/changeset/983bb16c726a/

Log:more debug output

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -16,13 +16,14 @@
 
 i = 0;
 cur = tmp_buf;
+cur += sprintf(cur, %p:, obj);
 while (flags[i]) {
 if (obj-h_tid  (STM_FIRST_GCFLAG  i)) {
 cur += sprintf(cur, %s|, flags[i]);
 }
 i++;
 }
-cur += sprintf(cur, tid=%ld\n, stm_get_tid(obj));
+cur += sprintf(cur, tid=%ld, stm_get_tid(obj));
 return tmp_buf;
 }
 #endif
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -27,10 +27,11 @@
 if (obj-h_tid  GCFLAG_IMMUTABLE) {
 assert(!(obj-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED));
 if (obj-h_tid  GCFLAG_PUBLIC) {
-/* young public */
+/* young public, replace with stolen old copy */
 assert(obj-h_tid  GCFLAG_NURSERY_MOVED);
 assert(IS_POINTER(obj-h_revision));
 stub = (gcptr)obj-h_revision;
+assert(!IS_POINTER(stub-h_revision)); /* not outdated */
 goto done;
 }
 
@@ -52,10 +53,10 @@
 if (!(obj-h_original))
 obj-h_original = (revision_t)O;
 }
+obj-h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
 obj-h_revision = (revision_t)O;
 
 O-h_tid |= GCFLAG_PUBLIC;
-obj-h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
 /* here it is fine if it stays in read caches because
the object is immutable anyway and there are no
write_barriers allowed. */
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -41,9 +41,13 @@
 
 if (is_in_nursery(d, pointing_to)) {
 if (pointing_to-h_tid  GCFLAG_NURSERY_MOVED) {
+dprintf((weakref ptr moved %p-%p\n, 
+ WEAKREF_PTR(weakref, size),
+ (gcptr)pointing_to-h_revision));
 WEAKREF_PTR(weakref, size) = (gcptr)pointing_to-h_revision;
 }
 else {
+dprintf((weakref lost ptr %p\n, WEAKREF_PTR(weakref, size)));
 WEAKREF_PTR(weakref, size) = NULL;
 continue;   /* no need to remember this weakref any longer */
 }
@@ -143,6 +147,10 @@
 assert(pointing_to != NULL);
 if (is_partially_visited(pointing_to)) {
 pointing_to = stmgcpage_visit(pointing_to);
+dprintf((mweakref ptr moved %p-%p\n,
+ WEAKREF_PTR(weakref, size),
+ pointing_to));
+
 assert(pointing_to-h_tid  GCFLAG_VISITED);
 WEAKREF_PTR(weakref, size) = pointing_to;
 }
@@ -169,6 +177,7 @@
 if (pointing_to-h_tid  GCFLAG_VISITED) {
 continue;   /* the target stays alive, the weakref remains */
 }
+dprintf((mweakref lost ptr %p\n, WEAKREF_PTR(weakref, size)));
 WEAKREF_PTR(weakref, size) = NULL;  /* the target dies */
 }
 /* remove this weakref from the list */
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: more backout

2013-07-19 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: 
Changeset: r420:d7b329c4c608
Date: 2013-07-19 11:52 +0200
http://bitbucket.org/pypy/stmgc/changeset/d7b329c4c608/

Log:more backout

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -358,19 +358,6 @@
 
 stmgc_trace(obj, visit_if_young);
 }
-
-while (gcptrlist_size(private_or_protected_roots)  0) {
-gcptr obj = gcptrlist_pop(private_or_protected_roots);
-/* if it has the write_barrier flag, clear it so that
-   it doesn't get inserted twice by a later write-barrier */
-if (obj-h_tid  GCFLAG_WRITE_BARRIER) {
-/* only insert those that were in old_obj_to_trace
-   and that we didn't insert already */
-obj-h_tid = ~GCFLAG_WRITE_BARRIER;
-gcptrlist_insert(d-old_objects_to_trace, obj);
-dprintf((re-add %p to old_objects_to_trace\n, obj));
-}
-}
 }
 
 static void fix_list_of_read_objects(struct tx_descriptor *d)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] stmgc default: demo_random should not use the writeables cache anymore, since that is invalid again

2013-07-19 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: 
Changeset: r421:5f6c08c9274a
Date: 2013-07-19 12:06 +0200
http://bitbucket.org/pypy/stmgc/changeset/5f6c08c9274a/

Log:demo_random should not use the writeables cache anymore, since that
is invalid again

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -53,11 +53,6 @@
 time_t default_seed;
 gcptr shared_roots[SHARED_ROOTS];
 
-#define CACHE_MASK 65535
-#define CACHE_ENTRIES ((CACHE_MASK + 1) / sizeof(char *))
-#define CACHE_AT(cache, obj) (*(gcptr *)((char *)(cache)   \
- + ((revision_t)(obj)  CACHE_MASK)))
-
 struct thread_data {
 unsigned int thread_seed;
 gcptr roots[MAXROOTS];
@@ -67,7 +62,6 @@
 int steps_left;
 int interruptible;
 int atomic;
-revision_t writeable[CACHE_ENTRIES];
 };
 __thread struct thread_data td;
 
@@ -137,7 +131,7 @@
 return x;
 }
 
-void push_roots(int with_cache)
+void push_roots()
 {
 int i;
 for (i = 0; i  td.num_roots; i++) {
@@ -145,30 +139,11 @@
 if (td.roots[i])
 stm_push_root(td.roots[i]);
 }
-
-if (with_cache) {
-stm_push_root(NULL);
-for (i = 0; i  CACHE_ENTRIES; i++) {
-if (td.writeable[i])
-stm_push_root((gcptr)td.writeable[i]);
-}
-}
 }
 
-void pop_roots(int with_cache)
+void pop_roots()
 {
 int i;
-/* some objects may have changed positions */
-memset(td.writeable, 0, sizeof(td.writeable));
-
-if (with_cache) {
-gcptr obj = stm_pop_root();
-while (obj) {
-CACHE_AT(td.writeable, obj) = obj;
-obj = stm_pop_root();
-}
-}
-
 for (i = td.num_roots - 1; i = 0; i--) {
 if (td.roots[i])
 td.roots[i] = stm_pop_root();
@@ -186,9 +161,9 @@
 nodeptr allocate_node()
 {
 nodeptr r;
-push_roots(1);
+push_roots();
 r = (nodeptr)stm_allocate(sizeof(struct node), GCTID_STRUCT_NODE);
-pop_roots(1);
+pop_roots();
 return r;
 }
 
@@ -252,7 +227,6 @@
 if (p != NULL) {
 check(p);
 w = stm_write_barrier(p);
-CACHE_AT(td.writeable, w) = w;
 check(w);
 assert(is_private(w));
 }
@@ -369,22 +343,22 @@
 {
 int k = get_rand(100);
 if (k  10) {
-push_roots(1);
+push_roots();
 stm_push_root(p);
 stm_become_inevitable(fun);
 p = stm_pop_root();
-pop_roots(1);
+pop_roots();
 } 
 else if (k  40) {
-push_roots(1);
+push_roots();
 stmgc_minor_collect();
-pop_roots(1);
+pop_roots();
 p = NULL;
 } else if (k  41  DO_MAJOR_COLLECTS) {
 fprintf(stdout, major collect\n);
-push_roots(1);
+push_roots();
 stmgcpage_possibly_major_collect(1);
-pop_roots(1);
+pop_roots();
 p = NULL;
 }
 return p;
@@ -423,10 +397,7 @@
 break;
 case 7: // set 'p' as *next in one of the roots
 check(_r);
-if (CACHE_AT(td.writeable, _r) == _r)
-w_r = (nodeptr)_r;
-else
-w_r = (nodeptr)write_barrier(_r);
+w_r = (nodeptr)write_barrier(_r);
 check((gcptr)w_r);
 check(p);
 w_r-next = (struct node*)p;
@@ -485,10 +456,7 @@
 assert(w_t-id == stm_id((gcptr)_t));
 }
 else {
-if (CACHE_AT(td.writeable, _t) == _t)
-w_t = (nodeptr)_t;
-else
-w_t = (nodeptr)write_barrier(_t);
+w_t = (nodeptr)write_barrier(_t);
 w_t-id = stm_id((gcptr)w_t);
 assert(w_t-id == stm_id((gcptr)_t));
 }
@@ -504,10 +472,7 @@
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
 else {
-if (CACHE_AT(td.writeable, _t) == _t)
-w_t = (nodeptr)_t;
-else
-w_t = (nodeptr)write_barrier(_t);
+w_t = (nodeptr)write_barrier(_t);
 w_t-hash = stm_hash((gcptr)w_t);
 assert(w_t-hash == stm_hash((gcptr)_t));
 }
@@ -563,7 +528,7 @@
 
 void transaction_break()
 {
-push_roots(0);
+push_roots();
 td.interruptible = 1;
 
 copy_roots(td.roots, td.roots_outside_perform, td.num_roots);
@@ -575,9 +540,7 @@
 copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
 
 td.interruptible = 0;
-pop_roots(0);
-
-/* done by pop_roots() memset(td.writeable, 0, sizeof(td.writeable)); */
+pop_roots();
 }
 
 
@@ -592,8 +555,8 @@
 assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF);
 arg1 = stm_pop_root();
 assert(arg1 == NULL);
-pop_roots(0);
-push_roots(0);
+pop_roots();
+push_roots();
 stm_push_root(arg1);
 stm_push_root(end_marker);
 
@@ -609,9 +572,6 @@
 {
 gcptr p = NULL;
 
-// clear cache of writeables:
-memset(td.writeable, 0, 

[pypy-commit] stmgc default: Backed out changeset: 191c168da60e (readding of objects during minor collections to old_objects_to_trace)

2013-07-19 Thread Raemi
Author: Remi Meier remi.me...@gmail.com
Branch: 
Changeset: r419:ff208391e85c
Date: 2013-07-19 11:51 +0200
http://bitbucket.org/pypy/stmgc/changeset/ff208391e85c/

Log:Backed out changeset: 191c168da60e (readding of objects during minor
collections to old_objects_to_trace)

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -125,9 +125,6 @@
 }
 
 //
-/* list for private/protected, old roots that need to be
-   kept in old_objects_to_trace */
-static __thread struct GcPtrList private_or_protected_roots = {0, 0, NULL};
 
 static inline gcptr create_old_object_copy(gcptr obj)
 {
@@ -207,22 +204,6 @@
(revision_t)END_MARKER_ON)) {
 /* 'item' is a regular, non-null pointer */
 visit_if_young(end);
-item = *end;
-/* if private or protected, this object needs to be
-   traced again in the next minor_collect if it is
-   currently in old_objects_to_trace. Because then
-   it may be seen as write-ready in the view of
-   someone:
-   pw = write_barrier(); push_root(pw);
-   minor_collect(); pw = pop_root(); // pw still write-ready
-*/
-if (item
- !(item-h_tid  GCFLAG_WRITE_BARRIER) /* not set in
-  obj_to_trace*/
- (item-h_tid  GCFLAG_PRIVATE_FROM_PROTECTED
-|| item-h_revision == stm_private_rev_num)) {
-gcptrlist_insert(private_or_protected_roots, item);
-}
 }
 else if (item != NULL) {
 if (item == END_MARKER_OFF)
@@ -545,15 +526,10 @@
d-num_read_objects_known_old);
 assert(gcptrlist_size(d-private_from_protected) =
d-num_private_from_protected_known_old);
-#if 0
-/* we could here force the following, but there is little point
-   and it's a bad idea to do things in this function that is
-   compiled only in debug mode */
 d-num_read_objects_known_old =
 gcptrlist_size(d-list_of_read_objects);
 d-num_private_from_protected_known_old =
 gcptrlist_size(d-private_from_protected);
-#endif
 return 0;
 }
 else {
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
@@ -205,6 +205,7 @@
 assert list_of_read_objects() == [p2]
 
 def test_write_barrier_after_minor_collect():
+# should fail
 p = oalloc_refs(1)
 pw = lib.stm_write_barrier(p)
 
@@ -220,8 +221,10 @@
 assert pw.h_tid  GCFLAG_OLD
 rawsetptr(pw, 0, r)
 
-# pw needs to be readded to old_objects_to_trace
-# before the next minor gc in order for this test to pass
+# pw not in old_objects_to_trace. A
+# repeated write_barrier before
+# rawsetptr() would fix that
+
 lib.stm_push_root(r)
 minor_collect()
 minor_collect()
@@ -232,24 +235,13 @@
 
 pr = lib.stm_read_barrier(p)
 assert r != r2
+# these will fail because pw/pr was
+# not traced in the last minor_collect,
+# because they were not registered in
+# old_objects_to_trace.
 assert getptr(pr, 0) != r
 assert getptr(pr, 0) == r2
 
-# the following shouldn't be done
-# because pw was not saved. Just
-# here to check that pw gets removed
-# from old_objects_to_trace when not found
-# on the root stack anymore
-rawsetptr(pw, 0, q)
-lib.stm_push_root(q)
-minor_collect()
-q2 = lib.stm_pop_root()
-check_nursery_free(q)
-pr = lib.stm_read_barrier(p)
-assert q != q2
-assert getptr(pr, 0) == q
-assert getptr(pr, 0) != q2
-
 def test_write_barrier_after_minor_collect_young_to_old():
 p = nalloc_refs(1)
 pw = lib.stm_write_barrier(p)
diff --git a/duhton/listobject.c b/duhton/listobject.c
--- a/duhton/listobject.c
+++ b/duhton/listobject.c
@@ -75,7 +75,7 @@
 
 void _list_append(DuListObject *ob, DuObject *x)
 {
-_du_write1(ob);
+_du_read1(ob);
 DuTupleObject *olditems = ob-ob_tuple;
 
 _du_read1(olditems);
@@ -85,6 +85,8 @@
 DuTupleObject *newitems = DuTuple_New(newcount);
 _du_restore3(ob, x, olditems);
 
+_du_write1(ob);
+
 for (i=0; inewcount-1; i++)
 newitems-ob_items[i] = olditems-ob_items[i];
 newitems-ob_items[newcount-1] = x;
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


  1   2   3   4   5   6   7   8   9   10   >