Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r66827:bdd86d602300
Date: 2013-09-07 14:35 +0200
http://bitbucket.org/pypy/pypy/changeset/bdd86d602300/

Log:    import stmgc

diff --git a/rpython/translator/stm/src_stm/et.c 
b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -25,7 +25,7 @@
     }
     cur += sprintf(cur, "tid=%ld", stm_get_tid(obj));
     cur += sprintf(cur, " : rev=%lx : orig=%lx", 
-                   (long)obj->h_revision, (long)obj->h_original);
+                   obj->h_revision, obj->h_original);
     return tmp_buf;
 }
 
@@ -951,8 +951,8 @@
         d->longest_abort_info_time = 0;   /* out of memory! */
       else
         {
-          if (stm_decode_abort_info(d, elapsed_time, num,
-                        (struct tx_abort_info *)d->longest_abort_info) != size)
+          if (stm_decode_abort_info(d, elapsed_time,
+                                     num, d->longest_abort_info) != size)
             stm_fatalerror("during stm abort: object mutated unexpectedly\n");
 
           d->longest_abort_info_time = elapsed_time;
diff --git a/rpython/translator/stm/src_stm/extra.c 
b/rpython/translator/stm/src_stm/extra.c
--- a/rpython/translator/stm/src_stm/extra.c
+++ b/rpython/translator/stm/src_stm/extra.c
@@ -236,75 +236,13 @@
 }
 
 size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time,
-                             int abort_reason, struct tx_abort_info *output)
+                             int abort_reason, char *output)
 {
-    /* Re-encodes the abort info as a single tx_abort_info structure.
-       This struct tx_abort_info is not visible to the outside, and used
-       only as an intermediate format that is fast to generate and without
-       requiring stm_read_barrier().
-     */
-    if (output != NULL) {
-        output->signature_packed = 127;
-        output->elapsed_time = elapsed_time;
-        output->abort_reason = abort_reason;
-        output->active = d->active;
-        output->atomic = d->atomic;
-        output->count_reads = d->count_reads;
-        output->reads_size_limit_nonatomic = d->reads_size_limit_nonatomic;
-    }
-
-    long num_words = 0;
-#define WRITE_WORD(word)   {                            \
-        if (output) output->words[num_words] = (word);  \
-        num_words++;                                    \
-    }
-
+    /* re-encodes the abort info as a single string.
+       For convenience (no escaping needed, no limit on integer
+       sizes, etc.) we follow the bittorrent format. */
+    size_t totalsize = 0;
     long i;
-    for (i=0; i<d->abortinfo.size; i+=2) {
-        char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]);
-        long *fieldoffsets = (long*)d->abortinfo.items[i+1];
-        long kind, offset;
-        while (*fieldoffsets != 0) {
-            kind = *fieldoffsets++;
-            WRITE_WORD(kind);
-            if (kind < 0) {
-                /* -1 is start of sublist; -2 is end of sublist */
-                continue;
-            }
-            offset = *fieldoffsets++;
-            switch(kind) {
-            case 1:    /* signed */
-            case 2:    /* unsigned */
-                WRITE_WORD(*(long *)(object + offset));
-                break;
-            case 3:    /* a string of bytes from the target object */
-                WRITE_WORD((revision_t)*(char **)(object + offset));
-                offset = *fieldoffsets++;   /* offset of len in the string */
-                WRITE_WORD(offset);
-                break;
-            default:
-                stm_fatalerror("corrupted abort log\n");
-            }
-        }
-    }
-    WRITE_WORD(0);
-#undef WRITE_WORD
-    return sizeof(struct tx_abort_info) + (num_words - 1) * sizeof(revision_t);
-}
-
-static size_t unpack_abort_info(struct tx_descriptor *d,
-                                struct tx_abort_info *ai,
-                                char *output)
-{
-    /* Lazily decodes a struct tx_abort_info into a single plain string.
-       For convenience (no escaping needed, no limit on integer
-       sizes, etc.) we follow the bittorrent format.  This makes the
-       format a bit more flexible for future changes.  The struct
-       tx_abort_info is still needed as an intermediate step, because
-       the string parameters may not be readable during an abort
-       (they may be stubs).
-    */
-    size_t totalsize = 0;
     char buffer[32];
     size_t res_size;
 #define WRITE(c)   { totalsize++; if (output) *output++=(c); }
@@ -315,74 +253,75 @@
                            }
     WRITE('l');
     WRITE('l');
-    res_size = sprintf(buffer, "i%llde", (long long)ai->elapsed_time);
+    res_size = sprintf(buffer, "i%llde", (long long)elapsed_time);
     WRITE_BUF(buffer, res_size);
-    res_size = sprintf(buffer, "i%de", (int)ai->abort_reason);
+    res_size = sprintf(buffer, "i%de", (int)abort_reason);
     WRITE_BUF(buffer, res_size);
     res_size = sprintf(buffer, "i%lde", (long)d->public_descriptor_index);
     WRITE_BUF(buffer, res_size);
-    res_size = sprintf(buffer, "i%lde", (long)ai->atomic);
+    res_size = sprintf(buffer, "i%lde", (long)d->atomic);
     WRITE_BUF(buffer, res_size);
-    res_size = sprintf(buffer, "i%de", (int)ai->active);
+    res_size = sprintf(buffer, "i%de", (int)d->active);
     WRITE_BUF(buffer, res_size);
-    res_size = sprintf(buffer, "i%lue", (unsigned long)ai->count_reads);
+    res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads);
     WRITE_BUF(buffer, res_size);
     res_size = sprintf(buffer, "i%lue",
-                       (unsigned long)ai->reads_size_limit_nonatomic);
+                       (unsigned long)d->reads_size_limit_nonatomic);
     WRITE_BUF(buffer, res_size);
     WRITE('e');
+    for (i=0; i<d->abortinfo.size; i+=2) {
+        char *object = (char*)stm_repeat_read_barrier(d->abortinfo.items[i+0]);
+        long *fieldoffsets = (long*)d->abortinfo.items[i+1];
+        long kind, offset;
+        size_t rps_size;
+        char *rps;
 
-    revision_t *src = ai->words;
-    while (*src != 0) {
-        long signed_value;
-        unsigned long unsigned_value;
-        char *rps;
-        long offset, rps_size;
-
-        switch (*src++) {
-
-        case -2:
-            WRITE('l');    /* '[', start of sublist */
-            break;
-
-        case -1:
-            WRITE('e');    /* ']', end of sublist */
-            break;
-
-        case 1:    /* signed */
-            signed_value = (long)(*src++);
-            res_size = sprintf(buffer, "i%lde", signed_value);
-            WRITE_BUF(buffer, res_size);
-            break;
-
-        case 2:    /* unsigned */
-            unsigned_value = (unsigned long)(*src++);
-            res_size = sprintf(buffer, "i%lue", unsigned_value);
-            WRITE_BUF(buffer, res_size);
-            break;
-
-        case 3:    /* a string of bytes from the target object */
-            rps = (char *)(*src++);
-            offset = *src++;
-            if (rps) {
-                rps = (char *)stm_read_barrier((gcptr)rps);
-                /* xxx a bit ad-hoc: it's a string whose length is a
-                 * long at 'rps_size'; the string data follows
-                 * immediately the length */
-                rps_size = *(long *)(rps + offset);
-                assert(rps_size >= 0);
-                res_size = sprintf(buffer, "%ld:", rps_size);
+        while (1) {
+            kind = *fieldoffsets++;
+            if (kind <= 0) {
+                if (kind == -2) {
+                    WRITE('l');    /* '[', start of sublist */
+                    continue;
+                }
+                if (kind == -1) {
+                    WRITE('e');    /* ']', end of sublist */
+                    continue;
+                }
+                break;   /* 0, terminator */
+            }
+            offset = *fieldoffsets++;
+            switch(kind) {
+            case 1:    /* signed */
+                res_size = sprintf(buffer, "i%lde",
+                                   *(long*)(object + offset));
                 WRITE_BUF(buffer, res_size);
-                WRITE_BUF(rps + offset + sizeof(long), rps_size);
+                break;
+            case 2:    /* unsigned */
+                res_size = sprintf(buffer, "i%lue",
+                                   *(unsigned long*)(object + offset));
+                WRITE_BUF(buffer, res_size);
+                break;
+            case 3:    /* a string of bytes from the target object */
+                rps = *(char **)(object + offset);
+                offset = *fieldoffsets++;
+                /* XXX think of a different hack: this one doesn't really
+                   work if we see stubs! */
+                if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) {
+                    /* xxx a bit ad-hoc: it's a string whose length is a
+                     * long at 'offset', following immediately the offset */
+                    rps_size = *(long *)(rps + offset);
+                    assert(rps_size >= 0);
+                    res_size = sprintf(buffer, "%zu:", rps_size);
+                    WRITE_BUF(buffer, res_size);
+                    WRITE_BUF(rps + offset + sizeof(long), rps_size);
+                }
+                else {
+                    WRITE_BUF("0:", 2);
+                }
+                break;
+            default:
+                stm_fatalerror("corrupted abort log\n");
             }
-            else {
-                /* write NULL as an empty string, good enough for now */
-                WRITE_BUF("0:", 2);
-            }
-            break;
-
-        default:
-            stm_fatalerror("corrupted abort log\n");
         }
     }
     WRITE('e');
@@ -397,53 +336,6 @@
     struct tx_descriptor *d = thread_descriptor;
     if (d->longest_abort_info_time <= 0)
         return NULL;
-
-    struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info;
-    assert(ai->signature_packed == 127);
-
-    stm_become_inevitable("stm_inspect_abort_info");
-
-    size_t size = unpack_abort_info(d, ai, NULL);
-    char *text = malloc(size);
-    if (text == NULL)
-        return NULL;   /* out of memory */
-    if (unpack_abort_info(d, ai, text) != size)
-        stm_fatalerror("stm_inspect_abort_info: "
-                       "object mutated unexpectedly\n");
-    free(ai);
-    d->longest_abort_info = text;
     d->longest_abort_info_time = 0;
     return d->longest_abort_info;
 }
-
-void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *))
-{
-    long i, size = d->abortinfo.size;
-    gcptr *items = d->abortinfo.items;
-    for (i = 0; i < size; i += 2) {
-        visit(&items[i]);
-        /* items[i+1] is not a gc ptr */
-    }
-
-    struct tx_abort_info *ai = (struct tx_abort_info *)d->longest_abort_info;
-    if (ai != NULL && ai->signature_packed == 127) {
-        revision_t *src = ai->words;
-        while (*src != 0) {
-            gcptr *rpps;
-
-            switch (*src++) {
-
-            case 1:    /* signed */
-            case 2:    /* unsigned */
-                src++;        /* ignore the value */
-                break;
-
-            case 3:
-                rpps = (gcptr *)(src++);
-                src++;        /* ignore the offset */
-                visit(rpps);  /* visit() the string object */
-                break;
-            }
-        }
-    }
-}
diff --git a/rpython/translator/stm/src_stm/extra.h 
b/rpython/translator/stm/src_stm/extra.h
--- a/rpython/translator/stm/src_stm/extra.h
+++ b/rpython/translator/stm/src_stm/extra.h
@@ -3,20 +3,8 @@
 #define _SRCSTM_EXTRA_H
 
 
-struct tx_abort_info {
-    char signature_packed;  /* 127 when the abort_info is in this format */
-    long long elapsed_time;
-    int abort_reason;
-    int active;
-    long atomic;
-    unsigned long count_reads;
-    unsigned long reads_size_limit_nonatomic;
-    revision_t words[1];    /* the 'words' list is a bytecode-like format */
-};
-
 void stm_copy_to_old_id_copy(gcptr obj, gcptr id);
 size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time,
-                             int abort_reason, struct tx_abort_info *output);
-void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *));
+                             int abort_reason, char *output);
 
 #endif
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
@@ -563,7 +563,12 @@
         visit_take_protected(&d->old_thread_local_obj);
 
         /* the abortinfo objects */
-        stm_visit_abort_info(d, &visit_take_protected);
+        long i, size = d->abortinfo.size;
+        gcptr *items = d->abortinfo.items;
+        for (i = 0; i < size; i += 2) {
+            visit_take_protected(&items[i]);
+            /* items[i+1] is not a gc ptr */
+        }
 
         /* the current transaction's private copies of public objects */
         wlog_t *item;
@@ -596,8 +601,8 @@
         } G2L_LOOP_END;
 
         /* reinsert to real pub_to_priv */
-        long i, size = new_public_to_private.size;
-        gcptr *items = new_public_to_private.items;
+        size = new_public_to_private.size;
+        items = new_public_to_private.items;
         for (i = 0; i < size; i += 2) {
             g2l_insert(&d->public_to_private, items[i], items[i + 1]);
         }
diff --git a/rpython/translator/stm/src_stm/nursery.c 
b/rpython/translator/stm/src_stm/nursery.c
--- a/rpython/translator/stm/src_stm/nursery.c
+++ b/rpython/translator/stm/src_stm/nursery.c
@@ -456,7 +456,12 @@
     visit_if_young(d->thread_local_obj_ref);
     visit_if_young(&d->old_thread_local_obj);
 
-    stm_visit_abort_info(d, &visit_if_young);
+    long i, size = d->abortinfo.size;
+    gcptr *items = d->abortinfo.items;
+    for (i = 0; i < size; i += 2) {
+        visit_if_young(&items[i]);
+        /* items[i+1] is not a gc ptr */
+    }
 }
 
 static void minor_collect(struct tx_descriptor *d)
diff --git a/rpython/translator/stm/src_stm/revision 
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-24b6be3aaa67
+8b92101281e9
diff --git a/rpython/translator/stm/src_stm/stmgc.h 
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -155,7 +155,7 @@
    stm_inspect_abort_info().  (XXX details not documented yet) */
 void stm_abort_info_push(gcptr obj, long fieldoffsets[]);
 void stm_abort_info_pop(long count);
-char *stm_inspect_abort_info(void);    /* turns inevitable */
+char *stm_inspect_abort_info(void);
 
 /* mostly for debugging support */
 void stm_abort_and_retry(void);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to