Ticket #1105: modified.alloca_optional.patch
File modified.alloca_optional.patch, 22.0 KB (added by jkeenan, 12 years ago) |
---|
-
src/pmc/nci.pmc
63 63 param_sig[j++] = 'P'; 64 64 case (INTVAL)'v': 65 65 break; 66 /* I have no idea how to handle these */67 66 case (INTVAL)'2': 68 67 case (INTVAL)'3': 69 68 case (INTVAL)'4': 70 param_sig[j++] = ' I';69 param_sig[j++] = 'P'; 71 70 break; 72 71 case (INTVAL)'@': 73 72 param_sig[j++] = '@'; -
t/steps/auto/libjit-01.t
6 6 use strict; 7 7 use warnings; 8 8 9 use Test::More tests => 34;9 use Test::More tests => 40; 10 10 use lib qw( lib t/configure/testlib ); 11 11 use Parrot::Configure; 12 12 use Parrot::Configure::Options 'process_options'; … … 107 107 108 108 $conf->data->set( 'cc_build_call_frames' => undef ); 109 109 $conf->data->set( 'has_exec_protect' => undef ); 110 $conf->data->set( 'libjit_has_alloca' => undef ); 110 111 $conf->data->set( 'libs' => '' ); 112 111 113 $has_libjit = 1; 112 114 $extra_libs = 'mylibs'; 115 $conf->data->set( 'cpuarch' => 'i386' ); 116 113 117 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 114 118 is( $conf->data->get( 'cc_build_call_frames' ), '-DCAN_BUILD_CALL_FRAMES', 115 119 "Got expected value for cc_build_call_frames" ); 116 120 ok( $conf->data->get( 'has_exec_protect' ), "has_exec_protect' set" ); 121 ok( $conf->data->get( 'libjit_has_alloca'), 122 "on i386 with libJIT, 'libjit_has_alloca' has true value" ); 117 123 is( $conf->data->get( 'libs' ), " $extra_libs", 118 124 "Got expected value for libs" ); 119 125 120 126 $conf->data->set( 'cc_build_call_frames' => undef ); 121 127 $conf->data->set( 'has_exec_protect' => undef ); 128 $conf->data->set( 'libjit_has_alloca' => undef ); 122 129 $conf->data->set( 'libs' => '' ); 130 131 $has_libjit = 1; 132 $extra_libs = 'mylibs'; 133 $conf->data->set( 'cpuarch' => 'ppc' ); 134 135 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 136 is( $conf->data->get( 'cc_build_call_frames' ), '-DCAN_BUILD_CALL_FRAMES', 137 "Got expected value for cc_build_call_frames" ); 138 ok( $conf->data->get( 'has_exec_protect' ), "has_exec_protect' set" ); 139 ok( ! $conf->data->get( 'libjit_has_alloca'), 140 "on non-i386 with libJIT, 'libjit_has_alloca' has false value" ); 141 is( $conf->data->get( 'libs' ), " $extra_libs", 142 "Got expected value for libs" ); 143 144 $conf->data->set( 'cc_build_call_frames' => undef ); 145 $conf->data->set( 'has_exec_protect' => undef ); 146 $conf->data->set( 'libjit_has_alloca' => undef ); 147 $conf->data->set( 'libs' => '' ); 148 123 149 $has_libjit = 0; 124 150 $extra_libs = 'mylibs'; 151 125 152 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 126 153 ok( ! defined($conf->data->get( 'cc_build_call_frames' )), 127 154 "cc_build_call_frames undefined as expected" ); 128 155 ok( ! defined($conf->data->get( 'has_exec_protect' )), 129 156 "has_exec_protect' undefined" ); 157 ok( ! $conf->data->get( 'libjit_has_alloca'), 158 "without libJIT, 'libjit_has_alloca' has false value" ); 130 159 is( $conf->data->get( 'libs' ), "", 131 160 "Got expected value for libs" ); 132 161 -
t/steps/gen/libjit-01.t
6 6 use strict; 7 7 use warnings; 8 8 9 use constant num_generated_files => 2; 10 use Test::More tests => 8 + 2*num_generated_files; 9 use constant NUM_GENERATED_FILES => 2; 10 # use Test::More tests => 8 + 2*NUM_GENERATED_FILES; 11 use Test::More qw( no_plan ); 11 12 12 13 use File::Copy 'move'; 13 14 use File::Temp 'tempfile'; … … 39 40 $conf->options->set( %$args ); 40 41 my $step = test_step_constructor_and_description($conf); 41 42 42 is( scalar keys %{$step->{targets}}, num_generated_files, "Expected number of generated files"); 43 is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}], "Templates match targets"); 43 is( scalar keys %{$step->{targets}}, NUM_GENERATED_FILES, 44 "Expected number of generated files"); 45 is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}], 46 "Templates match targets"); 44 47 45 48 foreach (keys %{$step->{templates}}) { 46 49 ok(-f $step->{templates}{$_}, "Able to locate $_ template") … … 56 59 57 60 my %orig_conf = map { $_ => $conf->data->get($_) } qw[ iv nv ]; 58 61 $conf->data->set( iv => 'int', nv => 'float' ); 62 # Set a value for 'libjit_has_alloca' to avoid uninitialized value warning. 63 $conf->data->set( 'libjit_has_alloca' => 1 ); 59 64 my $ret = $step->runstep($conf); 60 65 ok( $ret, "runstep() returned true value" ); 61 66 foreach (keys %{$step->{targets}}) { -
config/auto/libjit.pm
94 94 if ($has_libjit) { 95 95 $conf->data->set( 96 96 cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES', 97 has_exec_protect => 1, 97 has_exec_protect => 1, 98 libjit_has_alloca => ($conf->data->get('cpuarch') eq 'i386' ? '1' : '0'), 98 99 ); 99 100 $conf->data->add( ' ', libs => $extra_libs ); 100 101 } 102 else { 103 $conf->data->set( libjit_has_alloca => 0 ); 104 } 101 105 } 102 106 103 107 1; -
config/gen/libjit.pm
61 61 62 62 Parrot_init_arg_nci => [ qw(void_ptr void_ptr void_ptr) => 'void_ptr' ], 63 63 pmc_new_noinit => [ qw(void_ptr INTVAL) => 'void_ptr' ], 64 65 mem_sys_allocate => [ ('long') => 'void_ptr' ], 66 mem_sys_free => [ ('void_ptr') => 'void' ], 64 67 }, 65 68 ); 66 69 return \%data; -
config/gen/libjit/frame_builder_libjit_c.in
112 112 Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) { 113 113 struct jit_buffer_private_data *p; 114 114 jit_function_t f; 115 jit_value_t jit_interp, jit_func; 116 jit_type_t *jit_args_t; 117 jit_value_t *jit_args_v, *jit_regs; 115 jit_value_t jit_interp, jit_nci_pmc, jit_pcc_sig; 116 jit_value_t jit_func, jit_st; 118 117 119 118 /* populate private data */ 120 119 p = (struct jit_buffer_private_data*)priv; … … 127 126 /* start JIT function */ 128 127 { 129 128 jit_type_t arg_types[] = { 130 jit_type_void_ptr, /* interp */ 131 jit_type_void_ptr /* nci_info */ 129 jit_type_void_ptr, /* interp */ 130 jit_type_void_ptr, /* nci_pmc */ 131 jit_type_void_ptr /* pcc_sig */ 132 132 }; 133 jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 2, 1);133 jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 3, 1); 134 134 f = jit_function_create(p->ctx, f_sig); 135 135 } 136 136 137 137 /* get the incomming args */ 138 jit_interp = jit_value_get_param(f, 0); 139 jit_func = jit__vtable_get_pointer(f, jit_interp, jit_value_get_param(f, 1)); 138 jit_interp = jit_value_get_param(f, 0); 139 jit_nci_pmc = jit_value_get_param(f, 1); 140 jit_pcc_sig = jit_value_get_param(f, 2); 140 141 142 /* get the wrapped function */ 143 jit_func = jit__vtable_get_pointer(f, jit_interp, jit_nci_pmc); 144 145 /* allocate call_state */ 146 { 147 jit_value_t sizeof_call_state 148 = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); 149 jit_st = JIT_ALLOCA(f, sizeof_call_state); 150 } 151 152 /* init pcc */ 153 jit__Parrot_init_arg_nci(f, jit_interp, jit_st, jit_pcc_sig); 154 141 155 /* get the outgoing args */ 142 156 { 143 jit_value_t st; 144 int nargs; 157 int nargs = strlen(sig) - 1; 145 158 146 { 147 jit_value_t sizeof_call_state 148 = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); 149 st = jit_insn_alloca(f, sizeof_call_state); 150 } 159 jit_type_t jit_args_t[nargs]; 160 jit_value_t jit_args_v[nargs]; 161 jit_value_t jit_regs[nargs]; 151 162 152 nargs = Parrot_jit_parse_sig_args_pre(interp, sig, f, jit_interp,st,153 &jit_args_t, &jit_args_v, &jit_regs);163 Parrot_jit_parse_sig_args_pre(interp, sig, nargs, f, jit_interp, jit_st, 164 jit_args_t, jit_args_v, jit_regs); 154 165 155 166 /* get the return type */ 156 167 { … … 167 178 } 168 179 169 180 /* get the incomming return */ 170 Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, st, ret_v);181 Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, jit_st, ret_v); 171 182 } 172 183 173 184 /* clean up args */ 174 185 Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs); 175 186 } 176 187 188 /* deallocate call_state */ 189 JIT_ALLOCA_FREE(f, jit_st); 190 177 191 /* end JIT function */ 178 192 jit_insn_return(f, NULL); 179 193 … … 181 195 jit_function_compile(f); 182 196 jit_context_build_end(p->ctx); 183 197 184 mem_sys_free(jit_args_t);185 mem_sys_free(jit_args_v);186 mem_sys_free(jit_regs);187 188 198 return jit_function_to_closure(f); 189 199 } 190 200 191 int 192 Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, jit_function_t f,193 jit_ value_t jinterp, jit_value_t st,194 jit_type_t * *arg_types,195 jit_value_t * *arg_vals, jit_value_t **arg_regs) {196 int nargs, nregs,i, j;201 void 202 Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, int nargs, 203 jit_function_t f, jit_value_t jinterp, jit_value_t st, 204 jit_type_t *arg_types, 205 jit_value_t *arg_vals, jit_value_t *arg_regs) { 206 int i, j; 197 207 198 208 sig += 1; /* ignore return character */ 199 209 200 nargs = strlen(sig);201 nregs = Parrot_jit_init_pcc(sig, nargs, f, jinterp, st);202 203 *arg_types = (jit_type_t *)mem_sys_allocate(nargs * sizeof (jit_type_t));204 *arg_vals = (jit_value_t *)mem_sys_allocate(nargs * sizeof (jit_value_t));205 *arg_regs = (jit_value_t *)mem_sys_allocate(nregs * sizeof (jit_value_t));206 207 210 for (i = 0, j = 0; i < nargs; i++) { 208 211 char c; 209 212 jit_type_t t1; … … 212 215 case 'I': 213 216 t1 = JIT_TYPE_INTVAL; 214 217 read_int_reg: 215 (*arg_types)[i] = t1;216 v1 217 v2 218 (*arg_regs)[j++] = (*arg_vals)[i] = v2;218 arg_types[i] = t1; 219 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 220 v2 = jit__get_nci_I(f, jinterp, st, v1); 221 arg_regs[j++] = arg_vals[i] = v2; 219 222 break; 220 223 case 'c': 221 224 t1 = jit_type_sys_char; … … 233 236 case 'N': 234 237 t1 = JIT_TYPE_FLOATVAL; 235 238 read_float_reg: 236 (*arg_types)[i] = t1;237 v1 238 v2 239 (*arg_regs)[j++] = (*arg_vals)[i] = v2;239 arg_types[i] = t1; 240 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 241 v2 = jit__get_nci_N(f, jinterp, st, v1); 242 arg_regs[j++] = arg_vals[i] = v2; 240 243 break; 241 244 case 'f': 242 245 t1 = jit_type_sys_float; … … 246 249 goto read_float_reg; 247 250 248 251 case 'S': 249 (*arg_types)[i] = jit_type_void_ptr;250 v1 251 v2 252 (*arg_regs)[j++] = (*arg_vals)[i] = v2;252 arg_types[i] = jit_type_void_ptr; 253 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 254 v2 = jit__get_nci_S(f, jinterp, st, v1); 255 arg_regs[j++] = arg_vals[i] = v2; 253 256 break; 254 257 255 258 case 't': 256 (*arg_types)[i] = jit_type_void_ptr;257 v1 258 v2 259 (*arg_regs)[j++] = v2;260 (*arg_vals)[i] = jit__Parrot_str_to_cstring(f, jinterp, v2);259 arg_types[i] = jit_type_void_ptr; 260 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 261 v2 = jit__get_nci_S(f, jinterp, st, v1); 262 arg_regs[j++] = v2; 263 arg_vals[i] = jit__Parrot_str_to_cstring(f, jinterp, v2); 261 264 break; 262 265 263 266 case 'b': 264 (*arg_types)[i] = jit_type_void_ptr;265 v1 266 v2 267 (*arg_regs)[j++] = v2;268 (*arg_vals)[i] = jit__Buffer_bufstart(f, v2);267 arg_types[i] = jit_type_void_ptr; 268 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 269 v2 = jit__get_nci_S(f, jinterp, st, v1); 270 arg_regs[j++] = v2; 271 arg_vals[i] = jit__Buffer_bufstart(f, v2); 269 272 break; 270 273 case 'B': 271 (*arg_types)[i] = jit_type_void_ptr;272 v1 273 v2 274 (*arg_regs)[j++] = v2;275 v3 274 arg_types[i] = jit_type_void_ptr; 275 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 276 v2 = jit__get_nci_S(f, jinterp, st, v1); 277 arg_regs[j++] = v2; 278 v3 = jit__Parrot_str_to_cstring(f, jinterp, v2); 276 279 jit_value_set_addressable(v3); 277 (*arg_vals)[i] = jit_insn_address_of(f, v3);280 arg_vals[i] = jit_insn_address_of(f, v3); 278 281 break; 279 282 280 283 case 'p': 281 (*arg_types)[i] = jit_type_void_ptr;282 v1 283 v2 284 (*arg_regs)[j++] = (*arg_vals)[i] = v2;284 arg_types[i] = jit_type_void_ptr; 285 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 286 v2 = jit__get_nci_p(f, jinterp, st, v1); 287 arg_regs[j++] = arg_vals[i] = v2; 285 288 break; 286 289 case 'P': 287 290 case 'O': 288 291 case '@': 289 (*arg_types)[i] = jit_type_void_ptr;290 v1 291 v2 292 (*arg_regs)[j++] = (*arg_vals)[i] = v2;292 arg_types[i] = jit_type_void_ptr; 293 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 294 v2 = jit__get_nci_P(f, jinterp, st, v1); 295 arg_regs[j++] = arg_vals[i] = v2; 293 296 break; 294 297 case '2': 295 298 t1 = jit_type_sys_short; … … 300 303 case '4': 301 304 t1 = jit_type_sys_long; 302 305 call_get_integer: 303 (*arg_types)[i] = jit_type_void_ptr;304 v1 305 v2 306 (*arg_regs)[j++] = v2;307 v3 308 v4 306 arg_types[i] = jit_type_void_ptr; 307 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 308 v2 = jit__get_nci_P(f, jinterp, st, v1); 309 arg_regs[j++] = v2; 310 v3 = jit__vtable_get_integer(f, jinterp, v2); 311 v4 = jit_value_create(f, t1); 309 312 jit_value_set_addressable(v4); 310 313 jit_insn_store(f, v4, v3); 311 (*arg_vals)[i] = jit_insn_address_of(f, v4);314 arg_vals[i] = jit_insn_address_of(f, v4); 312 315 break; 313 316 314 317 case 'V': 315 (*arg_types)[i] = jit_type_void_ptr;316 v1 317 v2 318 (*arg_regs)[j++] = v2;319 v3 320 v4 318 arg_types[i] = jit_type_void_ptr; 319 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 320 v2 = jit__get_nci_P(f, jinterp, st, v1); 321 arg_regs[j++] = v2; 322 v3 = jit__vtable_get_pointer(f, jinterp, v2); 323 v4 = jit_value_create(f, jit_type_void_ptr); 321 324 jit_value_set_addressable(v4); 322 325 jit_insn_store(f, v4, v3); 323 (*arg_vals)[i] = jit_insn_address_of(f, v4);326 arg_vals[i] = jit_insn_address_of(f, v4); 324 327 break; 325 328 326 329 case '0': 327 (*arg_types)[i] = jit_type_void_ptr;328 (*arg_vals)[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL);330 arg_types[i] = jit_type_void_ptr; 331 arg_vals[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); 329 332 break; 330 333 331 334 case 'J': 332 (*arg_types)[i] = jit_type_void_ptr;333 (*arg_vals)[i] = jinterp;335 arg_types[i] = jit_type_void_ptr; 336 arg_vals[i] = jinterp; 334 337 break; 335 338 336 339 case 'U': 337 340 /* TODO */ 338 341 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 339 342 "arg type 'U' not yet implemented"); 340 return -1;343 return; 341 344 342 345 default: 343 346 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 344 347 "unkown arg type '%c'", c); 345 return -1;348 return; 346 349 } 347 350 } 348 349 return nargs;350 351 } 351 352 352 int353 Parrot_jit_init_pcc(char *sig, int nargs, jit_function_t f, jit_value_t interp, jit_value_t st) {354 int i, j;355 char pcc_sig[nargs];356 357 for (i = 0, j = 0; i < nargs; i++) {358 switch (sig[i]) {359 case 'I':360 case 'c':361 case 's':362 case 'i':363 case 'l':364 pcc_sig[j++] = 'I';365 break;366 367 case 'N':368 case 'f':369 case 'd':370 pcc_sig[j++] = 'N';371 break;372 373 case 'S':374 case 't':375 case 'b':376 case 'B':377 pcc_sig[j++] = 'S';378 break;379 380 case 'p':381 case 'P':382 case 'O':383 case 'V':384 case '2':385 case '3':386 case '4':387 pcc_sig[j++] = 'P';388 break;389 390 case '@':391 pcc_sig[j++] = '@';392 break;393 394 default:395 break;396 }397 }398 pcc_sig[j] = '\0';399 400 jit__Parrot_init_arg_nci(f, interp, st,401 jit_value_create_string_constant(f, pcc_sig, j+1));402 403 return j;404 }405 406 353 jit_type_t 407 354 Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) { 408 355 char c; … … 591 538 return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i); 592 539 } 593 540 594 jit_value_t595 jit_value_create_string_constant(jit_function_t f, char *str, int len) {596 jit_value_t jit_len, jit_str;597 int i;598 599 if (len < 1) {600 len = strlen(str);601 }602 603 jit_len = jit_value_create_nint_constant(f, jit_type_sys_int, len);604 jit_str = jit_insn_alloca(f, jit_len);605 606 for (i = 0; i < len; i++) {607 jit_value_t c = jit_value_create_nint_constant(f, jit_type_sys_char, str[i]);608 jit_insn_store_relative(f, jit_str, i, c);609 }610 611 return jit_str;612 }613 614 541 /* 615 542 * JIT wrappers 616 543 */ -
config/gen/libjit/frame_builder_libjit_h.in
33 33 * JIT types 34 34 */ 35 35 36 #define JIT_TYPE_UINTVAL @libjit_uv@ // jit_type_sys_ulong37 #define JIT_TYPE_INTVAL @libjit_iv@ // jit_type_sys_long38 #define JIT_TYPE_FLOATVAL @libjit_nv@ // jit_type_sys_double36 #define JIT_TYPE_UINTVAL @libjit_uv@ 37 #define JIT_TYPE_INTVAL @libjit_iv@ 38 #define JIT_TYPE_FLOATVAL @libjit_nv@ 39 39 40 40 /* 41 41 * JIT functions … … 44 44 void * 45 45 Parrot_jit_create_thunk(Interp *, char *, void *); 46 46 47 int 48 Parrot_jit_parse_sig_args_pre(Interp *, char *, jit_function_t, jit_value_t, jit_value_t,49 jit_type_t * *, jit_value_t **, jit_value_t **);47 void 48 Parrot_jit_parse_sig_args_pre(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t, 49 jit_type_t *, jit_value_t *, jit_value_t *); 50 50 51 int52 Parrot_jit_init_pcc(char *, int, jit_function_t, jit_value_t, jit_value_t);53 54 51 jit_type_t 55 52 Parrot_jit_parse_sig_ret_pre(Interp *, char *); 56 53 … … 63 60 jit_value_t 64 61 jit_value_create_intval_constant(jit_function_t, INTVAL); 65 62 66 jit_value_t 67 jit_value_create_string_constant(jit_function_t, char *, int); 63 /* 64 * workaround for platforms that lack libjit alloca support 65 */ 66 #if @libjit_has_alloca@ 67 # define JIT_ALLOCA(f, n) jit_insn_alloca(f, n) 68 # define JIT_ALLOCA_FREE(f, p) 69 #else 70 # define JIT_ALLOCA(f, n) jit__mem_sys_allocate(f, n) 71 # define JIT_ALLOCA_FREE(f, p) jit__mem_sys_free(f, p) 72 #endif 68 73 69 74 /* 70 75 * JIT wrappers