Ticket #1635: loopunroll2.patch
| File loopunroll2.patch, 6.5 KB (added by NotFound, 3 years ago) |
|---|
-
src/pmc/exception.pmc
751 751 RETURN(PMC *result); 752 752 } 753 753 754 /* 754 755 756 =item C<METHOD rewind(INTVAL pos)> 757 758 Discard 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 755 776 /* 756 777 757 778 =back -
src/pmc/exceptionhandler.pmc
300 300 : PMCNULL; 301 301 } 302 302 303 /* 304 305 =item C<METHOD rewind(INTVAL pos)> 306 307 Discard 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 303 328 } 304 329 305 330 /* -
src/call/ops.c
1 1 /* 2 Copyright (C) 2001-20 09, Parrot Foundation.2 Copyright (C) 2001-2010, Parrot Foundation. 3 3 $Id$ 4 4 5 5 =head1 NAME … … 35 35 /* HEADERIZER BEGIN: static */ 36 36 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 37 37 38 static void free_runloops_until(PARROT_INTERP, int id) 39 __attribute__nonnull__(1); 40 38 41 static void really_destroy_runloop_jump_points(PARROT_INTERP, 39 42 ARGFREE(Parrot_runloop *jump_point)) 40 43 __attribute__nonnull__(1); 41 44 45 #define ASSERT_ARGS_free_runloops_until __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 46 PARROT_ASSERT_ARG(interp)) 42 47 #define ASSERT_ARGS_really_destroy_runloop_jump_points \ 43 48 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 44 49 PARROT_ASSERT_ARG(interp)) … … 61 66 ASSERT_ARGS(runops) 62 67 volatile size_t offset = offs; 63 68 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; 66 71 67 72 /* It is OK if the runloop ID overflows; we only ever test it for equality, 68 73 so the chance of collision is slight. */ … … 82 87 #endif 83 88 { 84 89 new_runloop_jump_point(interp); 90 our_runloop_id = interp->current_runloop_id; 91 our_runloop_level = interp->current_runloop_level; 85 92 reenter: 86 93 interp->current_runloop->handler_start = NULL; 87 94 switch (setjmp(interp->current_runloop->resume)) { … … 101 108 case 2: 102 109 /* Reenter the runloop from a exception thrown from C 103 110 * with a pir handler */ 111 free_runloops_until(interp, our_runloop_id); 104 112 PARROT_ASSERT(interp->current_runloop->handler_start); 105 113 offset = interp->current_runloop->handler_start - interp->code->base.data; 106 114 /* Prevent incorrect reuse */ 107 115 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; 108 122 default: 109 123 break; 110 124 } … … 121 135 fprintf(stderr, "[exiting loop %d, level %d]\n", 122 136 our_runloop_id, our_runloop_level); 123 137 #endif 124 125 interp->current_runloop_level = our_runloop_level - 1;126 interp->current_runloop_id = old_runloop_id;127 138 } 128 139 129 140 … … 158 169 else 159 170 jump_point = mem_gc_allocate_zeroed_typed(interp, Parrot_runloop); 160 171 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; 163 177 } 164 178 165 179 /* … … 178 192 { 179 193 ASSERT_ARGS(free_runloop_jump_point) 180 194 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; 182 197 jump_point->prev = interp->runloop_jmp_free_list; 183 198 interp->runloop_jmp_free_list = jump_point; 199 interp->current_runloop_id = current ? current->id : 0; 200 --interp->current_runloop_level; 184 201 } 185 202 186 203 /* … … 204 221 205 222 /* 206 223 224 =item C<static void free_runloops_until(PARROT_INTERP, int id)> 225 226 Free runloops until the one with the provided id gets current. 227 228 =cut 229 230 */ 231 232 static void 233 free_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 207 241 =item C<static void really_destroy_runloop_jump_points(PARROT_INTERP, 208 242 Parrot_runloop *jump_point)> 209 243 -
include/parrot/call.h
28 28 struct parrot_runloop_t *prev; /* interpreter's runloop 29 29 * jump buffer stack */ 30 30 opcode_t *handler_start; /* Used in exception handling */ 31 int id; /* runloop id */ 31 32 32 33 /* let the biggest element cross the cacheline boundary */ 33 34 Parrot_jump_buff resume; /* jmp_buf */
