Author: chromatic
Date: Sat Nov  8 23:23:27 2008
New Revision: 32462

Modified:
   trunk/compilers/imcc/imc.h
   trunk/compilers/imcc/parser_util.c
   trunk/compilers/imcc/pbc.c
   trunk/compilers/imcc/pbc.h

Log:
[IMCC] Moved IMCC globals from a static struct into the IMCC_INFO struct in the
interpreter.  This helps make IMCC more reentrant (though it doesn't completely
fix RT #60000 for me).

Modified: trunk/compilers/imcc/imc.h
==============================================================================
--- trunk/compilers/imcc/imc.h  (original)
+++ trunk/compilers/imcc/imc.h  Sat Nov  8 23:23:27 2008
@@ -412,17 +412,15 @@
 
 struct nodeType_t;
 
-/*
- * see also imcc/imcc.l struct macro_frame_t
- */
+/* see also imcc/imcc.l struct macro_frame_t */
 struct parser_state_t {
     struct parser_state_t *next;
-    Interp *interp;
-    const char *file;
-    int file_needs_free; /* If *file is malloced, we need to free it */
-    FILE *handle;
-    int line;
-    int pasm_file;       /* pasm_file mode of this frame */
+    Interp                *interp;
+    const char            *file;
+    FILE                  *handle;
+    int                    file_needs_free; /* is *file malloced? */
+    int                    line;
+    int                    pasm_file;       /* pasm_file mode of this frame */
 };
 
 typedef enum _AsmState {
@@ -440,6 +438,36 @@
 PARROT_API void IMCC_push_parser_state(PARROT_INTERP);
 PARROT_API void IMCC_pop_parser_state(PARROT_INTERP, void *yyscanner);
 
+/* globals store the state between individual e_pbc_emit calls */
+typedef struct subs_t {
+    IMC_Unit      *unit;
+    struct subs_t *prev;
+    struct subs_t *next;
+    SymHash        fixup;              /* currently set_p_pc sub names only */
+    int            ins_line;           /* line number for debug */
+    int            n_basic_blocks;     /* block count */
+    int            pmc_const;          /* index in const table */
+    size_t         size;               /* code size in ops */
+} subs_t;
+
+/* subs are kept per code segment */
+typedef struct code_segment_t {
+    PackFile_ByteCode     *seg;           /* bytecode segment */
+    PackFile_Segment      *jit_info;      /* bblocks, register usage */
+    subs_t                *subs;          /* current sub data */
+    subs_t                *first;         /* first sub of code segment */
+    struct code_segment_t *prev;          /* previous code segment */
+    struct code_segment_t *next;          /* next code segment */
+    SymHash                key_consts;    /* this seg's cached key constants */
+    int                    pic_idx;       /* next index of PIC */
+} code_segment_t;
+
+typedef struct _imcc_globals_t {
+    code_segment_t *cs;           /* current code segment */
+    code_segment_t *first;        /* first code segment   */
+    int             inter_seg_n;
+} imcc_globals;
+
 typedef struct _imc_info_t {
     void                  *yyscanner;
     struct _imc_info_t    *prev;
@@ -463,6 +491,7 @@
     char                 *cur_macro_name;
 
     struct macro_frame_t *frames;
+    imcc_globals         *globals;
 
     char                 *macro_buffer;
     Hash                 *macros;

Modified: trunk/compilers/imcc/parser_util.c
==============================================================================
--- trunk/compilers/imcc/parser_util.c  (original)
+++ trunk/compilers/imcc/parser_util.c  Sat Nov  8 23:23:27 2008
@@ -933,6 +933,9 @@
 
     if (imc_info) {
         IMCC_INFO(interp) = imc_info->prev;
+        if (imc_info->globals)
+            mem_sys_free(imc_info->globals);
+
         mem_sys_free(imc_info);
     }
 

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c  (original)
+++ trunk/compilers/imcc/pbc.c  Sat Nov  8 23:23:27 2008
@@ -45,40 +45,6 @@
 
 */
 
-/*
- * globals store the state between individual e_pbc_emit calls
- */
-
-typedef struct subs_t {
-    size_t         size;               /* code size in ops */
-    int            ins_line;           /* line number for debug */
-    int            n_basic_blocks;     /* block count */
-    SymHash        fixup;              /* currently set_p_pc sub names only */
-    IMC_Unit      *unit;
-    int            pmc_const;          /* index in const table */
-    struct subs_t *prev;
-    struct subs_t *next;
-} subs_t;
-
-/* subs are kept per code segment */
-typedef struct code_segment_t {
-    PackFile_ByteCode     *seg;           /* bytecode segment */
-    PackFile_Segment      *jit_info;      /* bblocks, register usage */
-    subs_t                *subs;          /* current sub data */
-    subs_t                *first;         /* first sub of code segment */
-    struct code_segment_t *prev;          /* previous code segment */
-    struct code_segment_t *next;          /* next code segment */
-    SymHash                key_consts;    /* this seg's cached key constants */
-    int                    pic_idx;       /* next index of PIC */
-} code_segment_t;
-
-static struct globals {
-    code_segment_t *cs;               /* current code segment */
-    code_segment_t *first;            /* first code segment */
-    int             inter_seg_n;
-} globals;
-
-
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 
@@ -143,12 +109,14 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static subs_t * find_global_label(
+    PARROT_INTERP,
     ARGIN(const char *name),
     ARGIN(const subs_t *sym),
     ARGOUT(int *pc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
         FUNC_MODIFIES(*pc);
 
 PARROT_WARN_UNUSED_RESULT
@@ -179,8 +147,9 @@
     SHIM(int ex),
     SHIM(void *param));
 
-static void make_new_sub(ARGIN(IMC_Unit *unit))
-        __attribute__nonnull__(1);
+static void make_new_sub(PARROT_INTERP, ARGIN(IMC_Unit *unit))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
 
 static void make_pmc_const(PARROT_INTERP, ARGMOD(SymReg *r))
         __attribute__nonnull__(1)
@@ -194,7 +163,8 @@
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-static int old_blocks(void);
+static int old_blocks(PARROT_INTERP)
+        __attribute__nonnull__(1);
 
 PARROT_CONST_FUNCTION
 PARROT_WARN_UNUSED_RESULT
@@ -208,10 +178,13 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void store_key_const(ARGIN(const char *str), int idx)
+static void store_key_const(PARROT_INTERP, ARGIN(const char *str), int idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+static void store_sub_size(PARROT_INTERP, size_t size, size_t ins_line)
         __attribute__nonnull__(1);
 
-static void store_sub_size(size_t size, size_t ins_line);
 static void verify_signature(PARROT_INTERP,
     ARGIN(const Instruction *ins),
     ARGIN(opcode_t *pc))
@@ -225,7 +198,8 @@
 #ifdef HAS_JIT
 
 PARROT_WARN_UNUSED_RESULT
-static int old_blocks(void);
+static int old_blocks(PARROT_INTERP)
+        __attribute__nonnull__(1);
 
 #endif /* HAS_JIT */
 
@@ -240,9 +214,9 @@
 */
 
 static void
-imcc_globals_destroy(SHIM_INTERP, SHIM(int ex), SHIM(void *param))
+imcc_globals_destroy(PARROT_INTERP, SHIM(int ex), SHIM(void *param))
 {
-    code_segment_t *cs = globals.cs;
+    code_segment_t *cs = IMCC_INFO(interp)->globals->cs;
 
     while (cs) {
         subs_t         *s       = cs->subs;
@@ -260,7 +234,7 @@
         cs      = prev_cs;
     }
 
-    globals.cs = NULL;
+    IMCC_INFO(interp)->globals->cs = NULL;
 }
 
 
@@ -360,25 +334,27 @@
 {
     code_segment_t *cs = mem_allocate_zeroed_typed(code_segment_t);
 
-    /* register cleanup code */
-    if (!globals.cs)
-        Parrot_on_exit(interp, imcc_globals_destroy, NULL);
+    if (!IMCC_INFO(interp)->globals)
+        IMCC_INFO(interp)->globals = mem_allocate_zeroed_typed(imcc_globals);
 
-    cs->prev = globals.cs;
+    if (IMCC_INFO(interp)->globals->cs)
+        clear_sym_hash(&IMCC_INFO(interp)->globals->cs->key_consts);
+    else {
+        /* register cleanup code */
+        Parrot_on_exit(interp, imcc_globals_destroy, NULL);
+    }
 
     /* free previous cached key constants if any */
-    if (globals.cs)
-        clear_sym_hash(&globals.cs->key_consts);
-
     create_symhash(&cs->key_consts);
 
     cs->next     = NULL;
+    cs->prev     = IMCC_INFO(interp)->globals->cs;
     cs->subs     = NULL;
     cs->first    = NULL;
     cs->jit_info = NULL;
 
-    if (!globals.first)
-        globals.first = cs;
+    if (!IMCC_INFO(interp)->globals->first)
+        IMCC_INFO(interp)->globals->first = cs;
     else
         cs->prev->next = cs;
 
@@ -387,8 +363,7 @@
         PMC *self;
 
         cs->seg = interp->code =
-            PF_create_default_segs(interp,
-                    IMCC_INFO(interp)->state->file, 1);
+            PF_create_default_segs(interp, IMCC_INFO(interp)->state->file, 1);
 
         /*
          * create a PMC constant holding the interpreter state
@@ -401,7 +376,7 @@
         (void) add_const_table_pmc(interp, self);
     }
 
-    globals.cs = cs;
+    IMCC_INFO(interp)->globals->cs = cs;
 
     return 0;
 }
@@ -420,12 +395,12 @@
 
 PARROT_WARN_UNUSED_RESULT
 static int
-old_blocks(void)
+old_blocks(PARROT_INTERP)
 {
     size_t  size = 0;
     const   subs_t *s;
 
-    for (s = globals.cs->subs; s; s = s->prev) {
+    for (s = IMCC_INFO(interp)->globals->cs->subs; s; s = s->prev) {
         size += s->n_basic_blocks;
     }
 
@@ -447,30 +422,35 @@
 opcode_t *
 make_jit_info(PARROT_INTERP, ARGIN(const IMC_Unit *unit))
 {
-    const size_t old  = old_blocks();
+    const size_t old  = old_blocks(interp);
     const size_t size = unit->n_basic_blocks + old;
 
-    if (!globals.cs->jit_info) {
-        const  size_t len  = strlen(globals.cs->seg->base.name) + 5;
+    if (!IMCC_INFO(interp)->globals->cs->jit_info) {
+        const  size_t len  =
+            strlen(IMCC_INFO(interp)->globals->cs->seg->base.name) + 5;
         char * const  name = mem_allocate_n_typed(len, char);
 
-        snprintf(name, len, "%s_JIT", globals.cs->seg->base.name);
-        globals.cs->jit_info = PackFile_Segment_new_seg(interp,
+        snprintf(name, len, "%s_JIT",
+            IMCC_INFO(interp)->globals->cs->seg->base.name);
+
+        IMCC_INFO(interp)->globals->cs->jit_info =
+                PackFile_Segment_new_seg(interp,
                     interp->code->base.dir, PF_UNKNOWN_SEG, name, 1);
 
         mem_sys_free(name);
     }
 
     /* store current size */
-    globals.cs->subs->n_basic_blocks = unit->n_basic_blocks;
+    IMCC_INFO(interp)->globals->cs->subs->n_basic_blocks = 
unit->n_basic_blocks;
 
     /* offset of block start and end, 4 * registers_used */
-    globals.cs->jit_info->data =
-        mem_realloc_n_typed(globals.cs->jit_info->data, size * 4, opcode_t);
+    IMCC_INFO(interp)->globals->cs->jit_info->data =
+        mem_realloc_n_typed(IMCC_INFO(interp)->globals->cs->jit_info->data,
+            size * 4, opcode_t);
 
-    globals.cs->jit_info->size = size * 4;
+    IMCC_INFO(interp)->globals->cs->jit_info->size = size * 4;
 
-    return globals.cs->jit_info->data + old * 4;
+    return IMCC_INFO(interp)->globals->cs->jit_info->data + old * 4;
 }
 
 #endif /* HAS_JIT */
@@ -479,28 +459,28 @@
 
 =item C<static void make_new_sub>
 
-allocate a new globals.cs->subs structure
+allocate a new globals->cs->subs structure
 
 =cut
 
 */
 
 static void
-make_new_sub(ARGIN(IMC_Unit *unit))
+make_new_sub(PARROT_INTERP, ARGIN(IMC_Unit *unit))
 {
     subs_t * const s = mem_allocate_zeroed_typed(subs_t);
 
-    s->prev          = globals.cs->subs;
+    s->prev          = IMCC_INFO(interp)->globals->cs->subs;
     s->unit          = unit;
     s->pmc_const     = -1;
 
-    if (globals.cs->subs)
-        globals.cs->subs->next = s;
+    if (IMCC_INFO(interp)->globals->cs->subs)
+        IMCC_INFO(interp)->globals->cs->subs->next = s;
 
-    if (!globals.cs->first)
-        globals.cs->first = s;
+    if (!IMCC_INFO(interp)->globals->cs->first)
+        IMCC_INFO(interp)->globals->cs->first = s;
 
-    globals.cs->subs = s;
+    IMCC_INFO(interp)->globals->cs->subs = s;
 
     create_symhash(&s->fixup);
 }
@@ -523,9 +503,9 @@
 
     *ins_line   = 0;
 
-    if (globals.cs && interp->code->base.data) {
+    if (IMCC_INFO(interp)->globals->cs && interp->code->base.data) {
         subs_t *s;
-        for (s = globals.cs->subs; s; s = s->prev) {
+        for (s = IMCC_INFO(interp)->globals->cs->subs; s; s = s->prev) {
             size      += s->size;
             *ins_line += s->ins_line;
         }
@@ -545,10 +525,10 @@
 */
 
 static void
-store_sub_size(size_t size, size_t ins_line)
+store_sub_size(PARROT_INTERP, size_t size, size_t ins_line)
 {
-    globals.cs->subs->size     = size;
-    globals.cs->subs->ins_line = ins_line;
+    IMCC_INFO(interp)->globals->cs->subs->size     = size;
+    IMCC_INFO(interp)->globals->cs->subs->ins_line = ins_line;
 }
 
 /*
@@ -564,7 +544,7 @@
 static void
 store_fixup(PARROT_INTERP, ARGIN(const SymReg *r), int pc, int offset)
 {
-    SymReg * const fixup = _mk_address(interp, &globals.cs->subs->fixup,
+    SymReg * const fixup = _mk_address(interp, 
&IMCC_INFO(interp)->globals->cs->subs->fixup,
             r->name, U_add_all);
 
     if (r->set == 'p')
@@ -589,9 +569,10 @@
 */
 
 static void
-store_key_const(ARGIN(const char *str), int idx)
+store_key_const(PARROT_INTERP, ARGIN(const char *str), int idx)
 {
-    SymReg * const c = _mk_const(&globals.cs->key_consts, str, 0);
+    SymReg * const c =
+        _mk_const(&IMCC_INFO(interp)->globals->cs->key_consts, str, 0);
     c->color = idx;
 }
 
@@ -667,13 +648,14 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static subs_t *
-find_global_label(ARGIN(const char *name), ARGIN(const subs_t *sym), 
ARGOUT(int *pc))
+find_global_label(PARROT_INTERP, ARGIN(const char *name),
+    ARGIN(const subs_t *sym), ARGOUT(int *pc))
 {
     subs_t *s;
 
     *pc = 0;
 
-    for (s = globals.cs->first; s; s = s->next) {
+    for (s = IMCC_INFO(interp)->globals->cs->first; s; s = s->next) {
         SymReg * const r = s->unit->instructions->symregs[0];
 
         /* if names and namespaces are matching - ok */
@@ -705,7 +687,7 @@
     subs_t *s;
     int     jumppc = 0;
 
-    for (s = globals.cs->first; s; s = s->next) {
+    for (s = IMCC_INFO(interp)->globals->cs->first; s; s = s->next) {
         const SymHash * const hsh = &s->fixup;
         unsigned int          i;
 
@@ -717,7 +699,7 @@
                 int addr = jumppc + fixup->color;
 
                 /* check in matching namespace */
-                subs_t *s1 = find_global_label(fixup->name, s, &pc);
+                subs_t *s1 = find_global_label(interp, fixup->name, s, &pc);
 
                 /*
                  * if failed change opcode:
@@ -1051,7 +1033,7 @@
     if (!len)
         return NULL;
 
-    for (s = globals.cs->first; s; s = s->next) {
+    for (s = IMCC_INFO(interp)->globals->cs->first; s; s = s->next) {
         if (STREQ(s->unit->lexid->name, unit->outer->name)) {
             PObj_get_FLAGS(s->unit->sub_pmc) |= SUB_FLAG_IS_OUTER;
             return s->unit->sub_pmc;
@@ -1094,16 +1076,17 @@
     Parrot_sub          *sub;
 
     const int            k            = add_const_table(interp);
-    IMC_Unit            * const unit  = globals.cs->subs->unit;
     PackFile_ConstTable *ct           = interp->code->const_table;
     PackFile_Constant   *pfc          = ct->constants[k];
+    IMC_Unit            * const unit  =
+        IMCC_INFO(interp)->globals->cs->subs->unit;
 
     INTVAL               type         =
         (r->pcc_sub->calls_a_sub & ITPCCYIELD) ?
             enum_class_Coroutine :
                 unit->outer ? enum_class_Closure : enum_class_Sub;
 
-    globals.cs->subs->pmc_const       = k;
+    IMCC_INFO(interp)->globals->cs->subs->pmc_const = k;
 
     if (unit->_namespace) {
         /* strip namespace off from front */
@@ -1267,7 +1250,8 @@
     const opcode_t    *rc;
     PackFile_Constant *pfc;
 
-    const SymReg * const r = _get_sym(&globals.cs->key_consts, s_key);
+    const SymReg * const r =
+        _get_sym(&IMCC_INFO(interp)->globals->cs->key_consts, s_key);
 
     if (r)
         return r->color;
@@ -1284,7 +1268,7 @@
 
     k = add_const_table_key(interp, pfc->u.key);
 
-    store_key_const(s_key, k);
+    store_key_const(interp, s_key, k);
 
     IMCC_debug(interp, DEBUG_PBC_CONST, "\t=> %s #%d size %d\n",
                s_key, k, size);
@@ -1660,13 +1644,13 @@
 */
 
 int
-e_pbc_new_sub(SHIM_INTERP, SHIM(void *param), ARGIN(IMC_Unit *unit))
+e_pbc_new_sub(PARROT_INTERP, SHIM(void *param), ARGIN(IMC_Unit *unit))
 {
     if (!unit->instructions)
         return 0;
 
     /* we start a new compilation unit */
-    make_new_sub(unit);
+    make_new_sub(interp, unit);
 
     return 0;
 }
@@ -1704,9 +1688,13 @@
     pragma = ins->symregs[0]->pcc_sub->pragma;
 
     if (pragma & P_IMMEDIATE) {
+        imcc_globals *g            = IMCC_INFO(interp)->globals;
+        IMCC_INFO(interp)->globals = NULL;
+
         IMCC_debug(interp, DEBUG_PBC, "immediate sub '%s'",
                 ins->symregs[0]->name);
         PackFile_fixup_subs(interp, PBC_IMMEDIATE, NULL);
+        IMCC_INFO(interp)->globals = g;
     }
 
     return 0;
@@ -1828,7 +1816,7 @@
                 code_size, oldsize);
 
         constant_folding(interp, unit);
-        store_sub_size(code_size, ins_size);
+        store_sub_size(interp, code_size, ins_size);
 
         /*
          * allocate code and pic_index
@@ -1851,7 +1839,7 @@
 
         /* add debug if necessary */
         if (IMCC_INFO(interp)->optimizer_level == 0
-          || IMCC_INFO(interp)->optimizer_level == OPT_PASM) {
+        || IMCC_INFO(interp)->optimizer_level  == OPT_PASM) {
             const char * const sourcefile = unit->file;
 
             /* FIXME length and multiple subs */
@@ -1928,7 +1916,8 @@
              *
              * drawback: if we reach 0xffff, we'd have to resize again
              */
-            interp->code->pic_index->data[offs / 2] = ++globals.cs->pic_idx;
+            interp->code->pic_index->data[offs / 2] =
+                ++IMCC_INFO(interp)->globals->cs->pic_idx;
         }
 
         /* Start generating the bytecode */

Modified: trunk/compilers/imcc/pbc.h
==============================================================================
--- trunk/compilers/imcc/pbc.h  (original)
+++ trunk/compilers/imcc/pbc.h  Sat Nov  8 23:23:27 2008
@@ -24,7 +24,8 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-int e_pbc_new_sub(SHIM_INTERP, SHIM(void *param), ARGIN(IMC_Unit *unit))
+int e_pbc_new_sub(PARROT_INTERP, SHIM(void *param), ARGIN(IMC_Unit *unit))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
 int e_pbc_open(PARROT_INTERP, SHIM(void *param))

Reply via email to