github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-function.c (about) 1 /* 2 * jit-function.c - Functions for manipulating function blocks. 3 * 4 * Copyright (C) 2004, 2006-2008 Southern Storm Software, Pty Ltd. 5 * 6 * This file is part of the libjit library. 7 * 8 * The libjit library is free software: you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation, either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * The libjit library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with the libjit library. If not, see 20 * <http://www.gnu.org/licenses/>. 21 */ 22 23 #include "jit-internal.h" 24 #include "jit-apply-func.h" 25 #include "jit-rules.h" 26 #include "jit-setjmp.h" 27 28 /*@ 29 * @deftypefun jit_function_t jit_function_create (jit_context_t @var{context}, jit_type_t @var{signature}) 30 * Create a new function block and associate it with a JIT context. 31 * Returns NULL if out of memory. 32 * 33 * A function persists for the lifetime of its containing context. 34 * It initially starts life in the "building" state, where the user 35 * constructs instructions that represents the function body. 36 * Once the build process is complete, the user calls 37 * @code{jit_function_compile} to convert it into its executable form. 38 * 39 * It is recommended that you call @code{jit_context_build_start} before 40 * calling @code{jit_function_create}, and then call 41 * @code{jit_context_build_end} after you have called 42 * @code{jit_function_compile}. This will protect the JIT's internal 43 * data structures within a multi-threaded environment. 44 * @end deftypefun 45 @*/ 46 jit_function_t 47 jit_function_create(jit_context_t context, jit_type_t signature) 48 { 49 jit_function_t func; 50 #if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) 51 unsigned char *trampoline; 52 #endif 53 54 /* Acquire the memory context */ 55 _jit_memory_lock(context); 56 if(!_jit_memory_ensure(context)) 57 { 58 _jit_memory_unlock(context); 59 return 0; 60 } 61 62 /* Allocate memory for the function and clear it */ 63 func = _jit_memory_alloc_function(context); 64 if(!func) 65 { 66 _jit_memory_unlock(context); 67 return 0; 68 } 69 70 #if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) 71 trampoline = (unsigned char *) _jit_memory_alloc_trampoline(context); 72 if(!trampoline) 73 { 74 _jit_memory_free_function(context, func); 75 _jit_memory_unlock(context); 76 return 0; 77 } 78 # if defined(jit_redirector_size) 79 func->redirector = trampoline; 80 trampoline += jit_redirector_size; 81 # endif 82 # if defined(jit_indirector_size) 83 func->indirector = trampoline; 84 # endif 85 #endif /* !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) */ 86 87 /* Release the memory context */ 88 _jit_memory_unlock(context); 89 90 /* Initialize the function block */ 91 func->context = context; 92 func->signature = jit_type_copy(signature); 93 func->optimization_level = JIT_OPTLEVEL_NORMAL; 94 95 #if !defined(JIT_BACKEND_INTERP) && defined(jit_redirector_size) 96 /* If we aren't using interpretation, then point the function's 97 initial entry point at the redirector, which in turn will 98 invoke the on-demand compiler */ 99 func->entry_point = _jit_create_redirector 100 (func->redirector, (void *) context->on_demand_driver, 101 func, jit_type_get_abi(signature)); 102 _jit_flush_exec(func->redirector, jit_redirector_size); 103 #endif 104 #if !defined(JIT_BACKEND_INTERP) && defined(jit_indirector_size) 105 _jit_create_indirector(func->indirector, (void**) &(func->entry_point)); 106 _jit_flush_exec(func->indirector, jit_indirector_size); 107 #endif 108 109 /* Add the function to the context list */ 110 func->next = 0; 111 func->prev = context->last_function; 112 if(context->last_function) 113 { 114 context->last_function->next = func; 115 } 116 else 117 { 118 context->functions = func; 119 } 120 context->last_function = func; 121 122 /* Return the function to the caller */ 123 return func; 124 } 125 126 /*@ 127 * @deftypefun jit_function_t jit_function_create_nested (jit_context_t @var{context}, jit_type_t @var{signature}, jit_function_t @var{parent}) 128 * Create a new function block and associate it with a JIT context. 129 * In addition, this function is nested inside the specified 130 * @var{parent} function and is able to access its parent's 131 * (and grandparent's) local variables. 132 * 133 * The front end is responsible for ensuring that the nested function 134 * is compiled before its parent. 135 * @end deftypefun 136 @*/ 137 jit_function_t jit_function_create_nested 138 (jit_context_t context, jit_type_t signature, jit_function_t parent) 139 { 140 jit_function_t func; 141 func = jit_function_create(context, signature); 142 if(!func) 143 { 144 return 0; 145 } 146 func->nested_parent = parent; 147 return func; 148 } 149 150 int _jit_function_ensure_builder(jit_function_t func) 151 { 152 /* Handle the easy cases first */ 153 if(!func) 154 { 155 return 0; 156 } 157 if(func->builder) 158 { 159 return 1; 160 } 161 162 /* Allocate memory for the builder and clear it */ 163 func->builder = jit_cnew(struct _jit_builder); 164 if(!(func->builder)) 165 { 166 return 0; 167 } 168 169 /* Cache the value of the JIT_OPTION_POSITION_INDEPENDENT option */ 170 func->builder->position_independent 171 = jit_context_get_meta_numeric( 172 func->context, JIT_OPTION_POSITION_INDEPENDENT); 173 174 /* Initialize the function builder */ 175 jit_memory_pool_init(&(func->builder->value_pool), struct _jit_value); 176 jit_memory_pool_init(&(func->builder->edge_pool), struct _jit_edge); 177 jit_memory_pool_init(&(func->builder->meta_pool), struct _jit_meta); 178 179 /* Create the entry block */ 180 if(!_jit_block_init(func)) 181 { 182 _jit_function_free_builder(func); 183 return 0; 184 } 185 186 /* Create instructions to initialize the incoming arguments */ 187 func->builder->current_block = func->builder->entry_block; 188 if(!_jit_create_entry_insns(func)) 189 { 190 _jit_function_free_builder(func); 191 return 0; 192 } 193 194 /* The current position is where initialization code will be 195 inserted by "jit_insn_move_blocks_to_start" */ 196 func->builder->init_block = func->builder->current_block; 197 198 /* Start first block for function body */ 199 if(!jit_insn_new_block(func)) 200 { 201 _jit_function_free_builder(func); 202 return 0; 203 } 204 205 /* The builder is ready to go */ 206 return 1; 207 } 208 209 void _jit_function_free_builder(jit_function_t func) 210 { 211 if(func->builder) 212 { 213 _jit_block_free(func); 214 jit_memory_pool_free(&(func->builder->edge_pool), 0); 215 jit_memory_pool_free(&(func->builder->value_pool), _jit_value_free); 216 jit_memory_pool_free(&(func->builder->meta_pool), _jit_meta_free_one); 217 jit_free(func->builder->param_values); 218 jit_free(func->builder->label_info); 219 jit_free(func->builder); 220 func->builder = 0; 221 func->is_optimized = 0; 222 } 223 } 224 225 void 226 _jit_function_destroy(jit_function_t func) 227 { 228 jit_context_t context; 229 230 if(!func) 231 { 232 return; 233 } 234 235 context = func->context; 236 if(func->next) 237 { 238 func->next->prev = func->prev; 239 } 240 else 241 { 242 context->last_function = func->prev; 243 } 244 if(func->prev) 245 { 246 func->prev->next = func->next; 247 } 248 else 249 { 250 context->functions = func->next; 251 } 252 253 _jit_function_free_builder(func); 254 _jit_varint_free_data(func->bytecode_offset); 255 jit_meta_destroy(&func->meta); 256 jit_type_free(func->signature); 257 258 _jit_memory_lock(context); 259 260 #if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) 261 # if defined(jit_redirector_size) 262 _jit_memory_free_trampoline(context, func->redirector); 263 # else 264 _jit_memory_free_trampoline(context, func->indirector); 265 # endif 266 #endif 267 _jit_memory_free_function(context, func); 268 269 _jit_memory_unlock(context); 270 } 271 272 /*@ 273 * @deftypefun void jit_function_abandon (jit_function_t @var{func}) 274 * Abandon this function during the build process. This should be called 275 * when you detect a fatal error that prevents the function from being 276 * properly built. The @var{func} object is completely destroyed and 277 * detached from its owning context. The function is left alone if 278 * it was already compiled. 279 * @end deftypefun 280 @*/ 281 void jit_function_abandon(jit_function_t func) 282 { 283 if(func && func->builder) 284 { 285 if(func->is_compiled) 286 { 287 /* We already compiled this function previously, but we 288 have tried to recompile it with new contents. Throw 289 away the builder, but keep the original version */ 290 _jit_function_free_builder(func); 291 } 292 else 293 { 294 /* This function was never compiled, so abandon entirely */ 295 _jit_function_destroy(func); 296 } 297 } 298 } 299 300 /*@ 301 * @deftypefun jit_context_t jit_function_get_context (jit_function_t @var{func}) 302 * Get the context associated with a function. 303 * @end deftypefun 304 @*/ 305 jit_context_t jit_function_get_context(jit_function_t func) 306 { 307 if(func) 308 { 309 return func->context; 310 } 311 else 312 { 313 return 0; 314 } 315 } 316 317 /*@ 318 * @deftypefun jit_type_t jit_function_get_signature (jit_function_t @var{func}) 319 * Get the signature associated with a function. 320 * @end deftypefun 321 @*/ 322 jit_type_t jit_function_get_signature(jit_function_t func) 323 { 324 if(func) 325 { 326 return func->signature; 327 } 328 else 329 { 330 return 0; 331 } 332 } 333 334 /*@ 335 * @deftypefun int jit_function_set_meta (jit_function_t @var{func}, int @var{type}, void *@var{data}, jit_meta_free_func @var{free_data}, int @var{build_only}) 336 * Tag a function with some metadata. Returns zero if out of memory. 337 * 338 * Metadata may be used to store dependency graphs, branch prediction 339 * information, or any other information that is useful to optimizers 340 * or code generators. It can also be used by higher level user code 341 * to store information about the function that is specific to the 342 * virtual machine or language. 343 * 344 * If the @var{type} already has some metadata associated with it, then 345 * the previous value will be freed. 346 * 347 * If @var{build_only} is non-zero, then the metadata will be freed 348 * when the function is compiled with @code{jit_function_compile}. 349 * Otherwise the metadata will persist until the JIT context is destroyed, 350 * or @code{jit_function_free_meta} is called for the specified @var{type}. 351 * 352 * Metadata type values of 10000 or greater are reserved for internal use. 353 * @end deftypefun 354 @*/ 355 int jit_function_set_meta(jit_function_t func, int type, void *data, 356 jit_meta_free_func free_data, int build_only) 357 { 358 if(build_only) 359 { 360 if(!_jit_function_ensure_builder(func)) 361 { 362 return 0; 363 } 364 return jit_meta_set(&(func->builder->meta), type, data, 365 free_data, func); 366 } 367 else 368 { 369 return jit_meta_set(&(func->meta), type, data, free_data, 0); 370 } 371 } 372 373 /*@ 374 * @deftypefun {void *} jit_function_get_meta (jit_function_t @var{func}, int @var{type}) 375 * Get the metadata associated with a particular tag. Returns NULL 376 * if @var{type} does not have any metadata associated with it. 377 * @end deftypefun 378 @*/ 379 void *jit_function_get_meta(jit_function_t func, int type) 380 { 381 void *data = jit_meta_get(func->meta, type); 382 if(!data && func->builder) 383 { 384 data = jit_meta_get(func->builder->meta, type); 385 } 386 return data; 387 } 388 389 /*@ 390 * @deftypefun void jit_function_free_meta (jit_function_t @var{func}, int @var{type}) 391 * Free metadata of a specific type on a function. Does nothing if 392 * the @var{type} does not have any metadata associated with it. 393 * @end deftypefun 394 @*/ 395 void jit_function_free_meta(jit_function_t func, int type) 396 { 397 jit_meta_free(&(func->meta), type); 398 if(func->builder) 399 { 400 jit_meta_free(&(func->builder->meta), type); 401 } 402 } 403 404 /*@ 405 * @deftypefun jit_function_t jit_function_next (jit_context_t @var{context}, jit_function_t @var{prev}) 406 * Iterate over the defined functions in creation order. The @var{prev} 407 * argument should be NULL on the first call. Returns NULL at the end. 408 * @end deftypefun 409 @*/ 410 jit_function_t jit_function_next(jit_context_t context, jit_function_t prev) 411 { 412 if(prev) 413 { 414 return prev->next; 415 } 416 else if(context) 417 { 418 return context->functions; 419 } 420 else 421 { 422 return 0; 423 } 424 } 425 426 /*@ 427 * @deftypefun jit_function_t jit_function_previous (jit_context_t @var{context}, jit_function_t @var{prev}) 428 * Iterate over the defined functions in reverse creation order. 429 * @end deftypefun 430 @*/ 431 jit_function_t jit_function_previous(jit_context_t context, jit_function_t prev) 432 { 433 if(prev) 434 { 435 return prev->prev; 436 } 437 else if(context) 438 { 439 return context->last_function; 440 } 441 else 442 { 443 return 0; 444 } 445 } 446 447 /*@ 448 * @deftypefun jit_block_t jit_function_get_entry (jit_function_t @var{func}) 449 * Get the entry block for a function. This is always the first block 450 * created by @code{jit_function_create}. 451 * @end deftypefun 452 @*/ 453 jit_block_t jit_function_get_entry(jit_function_t func) 454 { 455 if(func && func->builder) 456 { 457 return func->builder->entry_block; 458 } 459 else 460 { 461 return 0; 462 } 463 } 464 465 /*@ 466 * @deftypefun jit_block_t jit_function_get_current (jit_function_t @var{func}) 467 * Get the current block for a function. New blocks are created by 468 * certain @code{jit_insn_xxx} calls. 469 * @end deftypefun 470 @*/ 471 jit_block_t jit_function_get_current(jit_function_t func) 472 { 473 if(func && func->builder) 474 { 475 return func->builder->current_block; 476 } 477 else 478 { 479 return 0; 480 } 481 } 482 483 /*@ 484 * @deftypefun jit_function_t jit_function_get_nested_parent (jit_function_t @var{func}) 485 * Get the nested parent for a function, or NULL if @var{func} 486 * does not have a nested parent. 487 * @end deftypefun 488 @*/ 489 jit_function_t jit_function_get_nested_parent(jit_function_t func) 490 { 491 if(func) 492 { 493 return func->nested_parent; 494 } 495 else 496 { 497 return 0; 498 } 499 } 500 501 /*@ 502 * @deftypefun jit_function_t jit_function_get_nested_parent (jit_function_t @var{func}, jit_value_t @var{parent_frame}) 503 * Set the frame pointer of the parent of a nested function 504 * @end deftypefun 505 @*/ 506 void jit_function_set_parent_frame(jit_function_t func, 507 jit_value_t parent_frame) 508 { 509 func->parent_frame = parent_frame; 510 func->cached_parent = NULL; 511 func->cached_parent_frame = NULL; 512 } 513 514 /* 515 * Information that is stored for an exception region in the cache. 516 */ 517 typedef struct jit_cache_eh *jit_cache_eh_t; 518 struct jit_cache_eh 519 { 520 jit_label_t handler_label; 521 unsigned char *handler; 522 jit_cache_eh_t previous; 523 }; 524 525 /*@ 526 * @deftypefun int jit_function_is_compiled (jit_function_t @var{func}) 527 * Determine if a function has already been compiled. 528 * @end deftypefun 529 @*/ 530 int jit_function_is_compiled(jit_function_t func) 531 { 532 if(func) 533 { 534 return func->is_compiled; 535 } 536 else 537 { 538 return 0; 539 } 540 } 541 542 /*@ 543 * @deftypefun int jit_function_set_recompilable (jit_function_t @var{func}) 544 * Mark this function as a candidate for recompilation. That is, 545 * it is possible that we may call @code{jit_function_compile} 546 * more than once, to re-optimize an existing function. 547 * 548 * It is very important that this be called before the first time that 549 * you call @code{jit_function_compile}. Functions that are recompilable 550 * are invoked in a slightly different way to non-recompilable functions. 551 * If you don't set this flag, then existing invocations of the function 552 * may continue to be sent to the original compiled version, not the new 553 * version. 554 * @end deftypefun 555 @*/ 556 void jit_function_set_recompilable(jit_function_t func) 557 { 558 if(func) 559 { 560 func->is_recompilable = 1; 561 } 562 } 563 564 /*@ 565 * @deftypefun void jit_function_clear_recompilable (jit_function_t @var{func}) 566 * Clear the recompilable flag on this function. Normally you would use 567 * this once you have decided that the function has been optimized enough, 568 * and that you no longer intend to call @code{jit_function_compile} again. 569 * 570 * Future uses of the function with @code{jit_insn_call} will output a 571 * direct call to the function, which is more efficient than calling 572 * its recompilable version. Pre-existing calls to the function may still 573 * use redirection stubs, and will remain so until the pre-existing 574 * functions are themselves recompiled. 575 * @end deftypefun 576 @*/ 577 void jit_function_clear_recompilable(jit_function_t func) 578 { 579 if(func) 580 { 581 func->is_recompilable = 0; 582 } 583 } 584 585 /*@ 586 * @deftypefun int jit_function_is_recompilable (jit_function_t @var{func}) 587 * Determine if this function is recompilable. 588 * @end deftypefun 589 @*/ 590 int jit_function_is_recompilable(jit_function_t func) 591 { 592 if(func) 593 { 594 return func->is_recompilable; 595 } 596 else 597 { 598 return 0; 599 } 600 } 601 602 #ifdef JIT_BACKEND_INTERP 603 604 /* 605 * Closure handling function for "jit_function_to_closure". 606 */ 607 static void function_closure(jit_type_t signature, void *result, 608 void **args, void *user_data) 609 { 610 if(!jit_function_apply((jit_function_t)user_data, args, result)) 611 { 612 /* We cannot report the exception through the closure, 613 so we have no choice but to rethrow it up the stack */ 614 jit_exception_throw(jit_exception_get_last()); 615 } 616 } 617 618 #endif /* JIT_BACKEND_INTERP */ 619 620 /*@ 621 * @deftypefun {void *} jit_function_to_closure (jit_function_t @var{func}) 622 * Convert a compiled function into a closure that can called directly 623 * from C. Returns NULL if out of memory, or if closures are not 624 * supported on this platform. 625 * 626 * If the function has not been compiled yet, then this will return 627 * a pointer to a redirector that will arrange for the function to be 628 * compiled on-demand when it is called. 629 * 630 * Creating a closure for a nested function is not recommended as 631 * C does not have any way to call such closures directly. 632 * @end deftypefun 633 @*/ 634 void *jit_function_to_closure(jit_function_t func) 635 { 636 if(!func) 637 { 638 return 0; 639 } 640 #ifdef JIT_BACKEND_INTERP 641 return jit_closure_create(func->context, func->signature, 642 function_closure, (void *)func); 643 #else 644 /* On native platforms, use the closure entry point */ 645 if(func->indirector && (!func->is_compiled || func->is_recompilable)) 646 { 647 return func->indirector; 648 } 649 return func->entry_point; 650 #endif 651 } 652 653 /*@ 654 * @deftypefun jit_function_t jit_function_from_closure (jit_context_t @var{context}, void *@var{closure}) 655 * Convert a closure back into a function. Returns NULL if the 656 * closure does not correspond to a function in the specified context. 657 * @end deftypefun 658 @*/ 659 jit_function_t 660 jit_function_from_closure(jit_context_t context, void *closure) 661 { 662 void *func_info; 663 664 if(!context) 665 { 666 return 0; 667 } 668 669 func_info = _jit_memory_find_function_info(context, closure); 670 if(!func_info) 671 { 672 return 0; 673 } 674 675 return _jit_memory_get_function(context, func_info); 676 } 677 678 /*@ 679 * @deftypefun jit_function_t jit_function_from_pc (jit_context_t @var{context}, void *@var{pc}, void **@var{handler}) 680 * Get the function that contains the specified program counter location. 681 * Also return the address of the @code{catch} handler for the same location. 682 * Returns NULL if the program counter does not correspond to a function 683 * under the control of @var{context}. 684 * @end deftypefun 685 @*/ 686 jit_function_t 687 jit_function_from_pc(jit_context_t context, void *pc, void **handler) 688 { 689 void *func_info; 690 jit_function_t func; 691 692 if(!context) 693 { 694 return 0; 695 } 696 697 /* Get the function and the exception handler cookie */ 698 func_info = _jit_memory_find_function_info(context, pc); 699 if(!func_info) 700 { 701 return 0; 702 } 703 func = _jit_memory_get_function(context, func_info); 704 if(!func) 705 { 706 return 0; 707 } 708 709 /* Convert the cookie into a handler address */ 710 if(handler) 711 { 712 #if 0 713 if(func->cookie) 714 { 715 *handler = ((jit_cache_eh_t) func->cookie)->handler; 716 } 717 else 718 { 719 *handler = 0; 720 } 721 #else 722 *handler = func->cookie; 723 #endif 724 } 725 return func; 726 } 727 728 /*@ 729 * @deftypefun {void *} jit_function_to_vtable_pointer (jit_function_t @var{func}) 730 * Return a pointer that is suitable for referring to this function 731 * from a vtable. Such pointers should only be used with the 732 * @code{jit_insn_call_vtable} instruction. 733 * 734 * Using @code{jit_insn_call_vtable} is generally more efficient than 735 * @code{jit_insn_call_indirect} for calling virtual methods. 736 * 737 * The vtable pointer might be the same as the closure, but this isn't 738 * guaranteed. Closures can be used with @code{jit_insn_call_indirect}. 739 * @end deftypefun 740 @*/ 741 void * 742 jit_function_to_vtable_pointer(jit_function_t func) 743 { 744 #ifdef JIT_BACKEND_INTERP 745 /* In the interpreted version, the function pointer is used in vtables */ 746 return func; 747 #else 748 /* On native platforms, the closure entry point is the vtable pointer */ 749 if(!func) 750 { 751 return 0; 752 } 753 if(func->indirector && (!func->is_compiled || func->is_recompilable)) 754 { 755 return func->indirector; 756 } 757 return func->entry_point; 758 #endif 759 } 760 761 /*@ 762 * @deftypefun jit_function_t jit_function_from_vtable_pointer (jit_context_t @var{context}, void *@var{vtable_pointer}) 763 * Convert a vtable_pointer back into a function. Returns NULL if the 764 * vtable_pointer does not correspond to a function in the specified context. 765 * @end deftypefun 766 @*/ 767 jit_function_t 768 jit_function_from_vtable_pointer(jit_context_t context, void *vtable_pointer) 769 { 770 #ifdef JIT_BACKEND_INTERP 771 /* In the interpreted version, the function pointer is used in vtables */ 772 jit_function_t func = (jit_function_t)vtable_pointer; 773 774 if(func && func->context == context) 775 { 776 return func; 777 } 778 return 0; 779 #else 780 void *func_info; 781 782 if(!context) 783 { 784 return 0; 785 } 786 787 func_info = _jit_memory_find_function_info(context, vtable_pointer); 788 if(!func_info) 789 { 790 return 0; 791 } 792 793 return _jit_memory_get_function(context, func_info); 794 #endif 795 } 796 797 /*@ 798 * @deftypefun void jit_function_set_on_demand_compiler (jit_function_t @var{func}, jit_on_demand_func @var{on_demand}) 799 * Specify the C function to be called when @var{func} needs to be 800 * compiled on-demand. This should be set just after the function 801 * is created, before any build or compile processes begin. 802 * 803 * You won't need an on-demand compiler if you always build and compile 804 * your functions before you call them. But if you can call a function 805 * before it is built, then you must supply an on-demand compiler. 806 * 807 * When on-demand compilation is requested, @code{libjit} takes the following 808 * actions: 809 * 810 * @enumerate 811 * @item 812 * The context is locked by calling @code{jit_context_build_start}. 813 * 814 * @item 815 * If the function has already been compiled, @code{libjit} unlocks 816 * the context and returns immediately. This can happen because of race 817 * conditions between threads: some other thread may have beaten us 818 * to the on-demand compiler. 819 * 820 * @item 821 * The user's on-demand compiler is called. It is responsible for building 822 * the instructions in the function's body. It should return one of the 823 * result codes @code{JIT_RESULT_OK}, @code{JIT_RESULT_COMPILE_ERROR}, 824 * or @code{JIT_RESULT_OUT_OF_MEMORY}. 825 * 826 * @item 827 * If the user's on-demand function hasn't already done so, @code{libjit} 828 * will call @code{jit_function_compile} to compile the function. 829 * 830 * @item 831 * The context is unlocked by calling @code{jit_context_build_end} and 832 * @code{libjit} jumps to the newly-compiled entry point. If an error 833 * occurs, a built-in exception of type @code{JIT_RESULT_COMPILE_ERROR} 834 * or @code{JIT_RESULT_OUT_OF_MEMORY} will be thrown. 835 * @end enumerate 836 * 837 * Normally you will need some kind of context information to tell you 838 * which higher-level construct is being compiled. You can use the 839 * metadata facility to add this context information to the function 840 * just after you create it with @code{jit_function_create}. 841 * @end deftypefun 842 @*/ 843 void 844 jit_function_set_on_demand_compiler(jit_function_t func, jit_on_demand_func on_demand) 845 { 846 if(func) 847 { 848 func->on_demand = on_demand; 849 } 850 } 851 852 /*@ 853 * @deftypefun jit_on_demand_func jit_function_get_on_demand_compiler (jit_function_t @var{func}) 854 * Returns function's on-demand compiler. 855 * @end deftypefun 856 @*/ 857 jit_on_demand_func 858 jit_function_get_on_demand_compiler(jit_function_t func) 859 { 860 if(func) 861 { 862 return func->on_demand; 863 } 864 return 0; 865 } 866 867 /*@ 868 * @deftypefun int jit_function_apply (jit_function_t @var{func}, void **@var{args}, void *@var{return_area}) 869 * Call the function @var{func} with the supplied arguments. Each element 870 * in @var{args} is a pointer to one of the arguments, and @var{return_area} 871 * points to a buffer to receive the return value. Returns zero if an 872 * exception occurred. 873 * 874 * This is the primary means for executing a function from ordinary 875 * C code without creating a closure first with @code{jit_function_to_closure}. 876 * Closures may not be supported on all platforms, but function application 877 * is guaranteed to be supported everywhere. 878 * 879 * Function applications acts as an exception blocker. If any exceptions 880 * occur during the execution of @var{func}, they won't travel up the 881 * stack any further than this point. This prevents ordinary C code 882 * from being accidentally presented with a situation that it cannot handle. 883 * This blocking protection is not present when a function is invoked 884 * via its closure. 885 * @end deftypefun 886 * 887 * @deftypefun int jit_function_apply_vararg (jit_function_t @var{func}, jit_type_t @var{signature}, void **@var{args}, void *@var{return_area}) 888 * Call the function @var{func} with the supplied arguments. There may 889 * be more arguments than are specified in the function's original signature, 890 * in which case the additional values are passed as variable arguments. 891 * This function is otherwise identical to @code{jit_function_apply}. 892 * @end deftypefun 893 @*/ 894 #if !defined(JIT_BACKEND_INTERP) 895 /* The interpreter version is in "jit-interp.cpp" */ 896 897 int jit_function_apply(jit_function_t func, void **args, void *return_area) 898 { 899 if(func) 900 { 901 return jit_function_apply_vararg 902 (func, func->signature, args, return_area); 903 } 904 else 905 { 906 return jit_function_apply_vararg(func, 0, args, return_area); 907 } 908 } 909 910 int jit_function_apply_vararg 911 (jit_function_t func, jit_type_t signature, void **args, void *return_area) 912 { 913 struct jit_backtrace call_trace; 914 void *entry; 915 jit_jmp_buf jbuf; 916 917 /* Establish a "setjmp" point here so that we can unwind the 918 stack to this point when an exception occurs and then prevent 919 the exception from propagating further up the stack */ 920 _jit_unwind_push_setjmp(&jbuf); 921 if(setjmp(jbuf.buf)) 922 { 923 _jit_unwind_pop_setjmp(); 924 return 0; 925 } 926 927 /* Create a backtrace entry that blocks exceptions from 928 flowing further than this up the stack */ 929 _jit_backtrace_push(&call_trace, 0); 930 931 /* Get the function's entry point */ 932 if(!func) 933 { 934 jit_exception_builtin(JIT_RESULT_NULL_FUNCTION); 935 return 0; 936 } 937 if(func->nested_parent) 938 { 939 jit_exception_builtin(JIT_RESULT_CALLED_NESTED); 940 return 0; 941 } 942 if(func->is_compiled) 943 { 944 entry = func->entry_point; 945 } 946 else 947 { 948 entry = (*func->context->on_demand_driver)(func); 949 } 950 951 /* Get the default signature if necessary */ 952 if(!signature) 953 { 954 signature = func->signature; 955 } 956 957 /* Clear the exception state */ 958 jit_exception_clear_last(); 959 960 /* Apply the function. If it returns, then there is no exception */ 961 jit_apply(signature, entry, args, jit_type_num_params(func->signature), return_area); 962 963 /* Restore the backtrace and "setjmp" contexts and exit */ 964 _jit_unwind_pop_setjmp(); 965 return 1; 966 } 967 968 #endif /* !JIT_BACKEND_INTERP */ 969 970 /*@ 971 * @deftypefun void jit_function_set_optimization_level (jit_function_t @var{func}, unsigned int @var{level}) 972 * Set the optimization level for @var{func}. Increasing values indicate 973 * that the @code{libjit} dynamic compiler should expend more effort to 974 * generate better code for this function. Usually you would increase 975 * this value just before forcing @var{func} to recompile. 976 * 977 * When the optimization level reaches the value returned by 978 * @code{jit_function_get_max_optimization_level()}, there is usually 979 * little point in continuing to recompile the function because 980 * @code{libjit} may not be able to do any better. 981 * 982 * The front end is usually responsible for choosing candidates for 983 * function inlining. If it has identified more such candidates, then 984 * it may still want to recompile @var{func} again even once it has 985 * reached the maximum optimization level. 986 * @end deftypefun 987 @*/ 988 void 989 jit_function_set_optimization_level(jit_function_t func, unsigned int level) 990 { 991 unsigned int max_level = jit_function_get_max_optimization_level(); 992 if(level > max_level) 993 { 994 level = max_level; 995 } 996 if(func) 997 { 998 func->optimization_level = level; 999 } 1000 } 1001 1002 /*@ 1003 * @deftypefun {unsigned int} jit_function_get_optimization_level (jit_function_t @var{func}) 1004 * Get the current optimization level for @var{func}. 1005 * @end deftypefun 1006 @*/ 1007 unsigned int 1008 jit_function_get_optimization_level(jit_function_t func) 1009 { 1010 if(func) 1011 { 1012 return func->optimization_level; 1013 } 1014 else 1015 { 1016 return JIT_OPTLEVEL_NONE; 1017 } 1018 } 1019 1020 /*@ 1021 * @deftypefun {unsigned int} jit_function_get_max_optimization_level (void) 1022 * Get the maximum optimization level that is supported by @code{libjit}. 1023 * @end deftypefun 1024 @*/ 1025 unsigned int 1026 jit_function_get_max_optimization_level(void) 1027 { 1028 return JIT_OPTLEVEL_NORMAL; 1029 } 1030 1031 /*@ 1032 * @deftypefun {jit_label_t} jit_function_reserve_label (jit_function_t @var{func}) 1033 * Allocate a new label for later use within the function @var{func}. Most 1034 * instructions that require a label could perform label allocation themselves. 1035 * A separate label allocation could be useful to fill a jump table with 1036 * identical entries. 1037 * @end deftypefun 1038 @*/ 1039 jit_label_t 1040 jit_function_reserve_label(jit_function_t func) 1041 { 1042 /* Ensure that we have a function builder */ 1043 if(!_jit_function_ensure_builder(func)) 1044 { 1045 return jit_label_undefined; 1046 } 1047 1048 return (func->builder->next_label)++; 1049 } 1050 1051 /*@ 1052 * @deftypefun {int} jit_function_labels_equal (jit_function_t @var{func}, jit_label_t @var{label}, jit_label_t @var{label2}) 1053 * Check if labels @var{label} and @var{label2} defined within the function 1054 * @var{func} are equal that is belong to the same basic block. Labels that 1055 * are not associated with any block are never considered equal. 1056 * @end deftypefun 1057 @*/ 1058 int 1059 jit_function_labels_equal(jit_function_t func, jit_label_t label, jit_label_t label2) 1060 { 1061 jit_block_t block, block2; 1062 1063 if(func && func->builder 1064 && label != jit_label_undefined 1065 && label2 != jit_label_undefined 1066 && label < func->builder->max_label_info 1067 && label2 < func->builder->max_label_info) 1068 { 1069 block = func->builder->label_info[label].block; 1070 if(block) 1071 { 1072 block2 = func->builder->label_info[label2].block; 1073 return block == block2; 1074 } 1075 } 1076 1077 return 0; 1078 }