Ticket #1635: loopunroll2.patch

File loopunroll2.patch, 6.5 KB (added by NotFound, 5 years ago)
  • src/pmc/exception.pmc

     
    751751        RETURN(PMC *result); 
    752752    } 
    753753 
     754/* 
    754755 
     756=item C<METHOD rewind(INTVAL pos)> 
     757 
     758Discard abandoned runloops when exception handling is done. EXPERIMENTAL. 
     759 
     760=cut 
     761 
     762*/ 
     763 
     764    METHOD rewind(INTVAL pos) { 
     765        PMC *iter; 
     766        GET_ATTR_handler_iter(INTERP, SELF, iter); 
     767        if (!PMC_IS_NULL(iter)) { 
     768            /* The active handler has been shifted, its current index 
     769             * within the iterator is -1 */ 
     770            PMC *handler = VTABLE_get_pmc_keyed_int(INTERP, iter, -1); 
     771            if (!PMC_IS_NULL(handler)) 
     772                Parrot_pcc_invoke_method_from_c_args(INTERP, handler, CONST_STRING(INTERP, "rewind"), "I->", pos); 
     773        } 
     774    } 
     775 
    755776/* 
    756777 
    757778=back 
  • src/pmc/exceptionhandler.pmc

     
    300300                : PMCNULL; 
    301301    } 
    302302 
     303/* 
     304 
     305=item C<METHOD rewind(INTVAL pos)> 
     306 
     307Discard abandoned runloops when exception handling is done. EXPERIMENTAL. 
     308 
     309=cut 
     310 
     311*/ 
     312 
     313    METHOD rewind(INTVAL pos) { 
     314        Parrot_runloop *rl = INTERP->current_runloop; 
     315        INTVAL rid; 
     316        GET_ATTR_runloop_id(INTERP, SELF, rid); 
     317        while (rl && rl->id != rid) 
     318            rl = rl->prev; 
     319        if (rl) { 
     320            rl->handler_start = (opcode_t *)pos; 
     321            longjmp(rl->resume, 3); 
     322        } 
     323        else 
     324            Parrot_ex_throw_from_c_args(INTERP, NULL, 
     325                    EXCEPTION_INVALID_OPERATION, "missing runloop"); 
     326    } 
     327 
    303328} 
    304329 
    305330/* 
  • src/call/ops.c

     
    11/* 
    2 Copyright (C) 2001-2009, Parrot Foundation. 
     2Copyright (C) 2001-2010, Parrot Foundation. 
    33$Id$ 
    44 
    55=head1 NAME 
     
    3535/* HEADERIZER BEGIN: static */ 
    3636/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */ 
    3737 
     38static void free_runloops_until(PARROT_INTERP, int id) 
     39        __attribute__nonnull__(1); 
     40 
    3841static void really_destroy_runloop_jump_points(PARROT_INTERP, 
    3942    ARGFREE(Parrot_runloop *jump_point)) 
    4043        __attribute__nonnull__(1); 
    4144 
     45#define ASSERT_ARGS_free_runloops_until __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
     46       PARROT_ASSERT_ARG(interp)) 
    4247#define ASSERT_ARGS_really_destroy_runloop_jump_points \ 
    4348     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    4449       PARROT_ASSERT_ARG(interp)) 
     
    6166    ASSERT_ARGS(runops) 
    6267    volatile size_t offset            = offs; 
    6368    const    int    old_runloop_id    = interp->current_runloop_id; 
    64     const    int    our_runloop_level = ++interp->current_runloop_level; 
    65     const    int    our_runloop_id    = ++runloop_id_counter; 
     69    int             our_runloop_level = interp->current_runloop_level; 
     70    int             our_runloop_id    = old_runloop_id; 
    6671 
    6772    /* It is OK if the runloop ID overflows; we only ever test it for equality, 
    6873       so the chance of collision is slight. */ 
     
    8287#endif 
    8388    { 
    8489        new_runloop_jump_point(interp); 
     90        our_runloop_id = interp->current_runloop_id; 
     91        our_runloop_level = interp->current_runloop_level; 
    8592  reenter: 
    8693        interp->current_runloop->handler_start = NULL; 
    8794        switch (setjmp(interp->current_runloop->resume)) { 
     
    101108          case 2: 
    102109            /* Reenter the runloop from a exception thrown from C 
    103110             * with a pir handler */ 
     111            free_runloops_until(interp, our_runloop_id); 
    104112            PARROT_ASSERT(interp->current_runloop->handler_start); 
    105113            offset = interp->current_runloop->handler_start - interp->code->base.data; 
    106114            /* Prevent incorrect reuse */ 
    107115            goto reenter; 
     116          case 3: 
     117            /* Reenter the runloop when finished the handling of a 
     118             * exception */ 
     119            free_runloops_until(interp, our_runloop_id); 
     120            offset = interp->current_runloop->handler_start - interp->code->base.data; 
     121            goto reenter; 
    108122          default: 
    109123            break; 
    110124        } 
     
    121135    fprintf(stderr, "[exiting loop %d, level %d]\n", 
    122136            our_runloop_id, our_runloop_level); 
    123137#endif 
    124  
    125     interp->current_runloop_level = our_runloop_level - 1; 
    126     interp->current_runloop_id    = old_runloop_id; 
    127138} 
    128139 
    129140 
     
    158169    else 
    159170        jump_point = mem_gc_allocate_zeroed_typed(interp, Parrot_runloop); 
    160171 
    161     jump_point->prev        = interp->current_runloop; 
    162     interp->current_runloop = jump_point; 
     172    jump_point->prev           = interp->current_runloop; 
     173    jump_point->id             = ++runloop_id_counter; 
     174    interp->current_runloop    = jump_point; 
     175    interp->current_runloop_id = jump_point->id; 
     176    ++interp->current_runloop_level; 
    163177} 
    164178 
    165179/* 
     
    178192{ 
    179193    ASSERT_ARGS(free_runloop_jump_point) 
    180194    Parrot_runloop * const jump_point = interp->current_runloop; 
    181     interp->current_runloop           = jump_point->prev; 
     195    Parrot_runloop * const current    = jump_point->prev; 
     196    interp->current_runloop           = current; 
    182197    jump_point->prev                  = interp->runloop_jmp_free_list; 
    183198    interp->runloop_jmp_free_list     = jump_point; 
     199    interp->current_runloop_id        = current ? current->id : 0; 
     200    --interp->current_runloop_level; 
    184201} 
    185202 
    186203/* 
     
    204221 
    205222/* 
    206223 
     224=item C<static void free_runloops_until(PARROT_INTERP, int id)> 
     225 
     226Free runloops until the one with the provided id gets current. 
     227 
     228=cut 
     229 
     230*/ 
     231 
     232static void 
     233free_runloops_until(PARROT_INTERP, int id) 
     234{ 
     235    while (interp->current_runloop && interp->current_runloop_id != id) 
     236        free_runloop_jump_point(interp); 
     237} 
     238 
     239/* 
     240 
    207241=item C<static void really_destroy_runloop_jump_points(PARROT_INTERP, 
    208242Parrot_runloop *jump_point)> 
    209243 
  • include/parrot/call.h

     
    2828    struct parrot_runloop_t *prev;          /* interpreter's runloop 
    2929                                             * jump buffer stack */ 
    3030    opcode_t                *handler_start; /* Used in exception handling */ 
     31    int                      id;            /* runloop id */ 
    3132 
    3233    /* let the biggest element cross the cacheline boundary */ 
    3334    Parrot_jump_buff         resume;        /* jmp_buf */